Hi,

I've started working on
http://opensource.atlassian.com/projects/hibernate/browse/HHH-1829 as
we're using a legacy database and need to do a join that doesn't use a
primary key. I have a working patch at the moment which seems to fix the
issue(at least for our uses), although I'm not sure how 'nice' it is.

When I looked through the code, I couldn't see the 'property-ref'
attribute in the <key> tag being stored anywhere so I have added it to
the KeyValue interface. This value is also stored in the
AbstractEntityPersister class, similarly to rootTableKeyColumnNames.
When the join is made, a check is performed to see if an alternative key
should be used in the join. If there is no property-ref specified then
the primary keys are used, otherwise the property-ref column is used.

Also, is it normal to get 6 failures and 7 errors when running 'ant
junitreport' (from trunk revision 10864)?

Attached is an svn diff of the changes I have made.

Thanks,
-- 
Andrew Seales

EDINA                   tel: +44 (0) 131 651 1430
Edinburgh University    fax: +44 (0) 131 650 3308
Main Library Building   url: http://edina.ac.uk
George Square           email: [EMAIL PROTECTED]
Edinburgh EH8 9LJ
Index: src/org/hibernate/cfg/HbmBinder.java
===================================================================
--- src/org/hibernate/cfg/HbmBinder.java	(revision 10864)
+++ src/org/hibernate/cfg/HbmBinder.java	(working copy)
@@ -1125,6 +1125,8 @@
 
 		Attribute fkNode = node.attribute( "foreign-key" );
 		if ( fkNode != null ) simpleValue.setForeignKeyName( fkNode.getValue() );
+		Attribute propertyRefNode = node.attribute( "property-ref" );
+		if ( propertyRefNode != null ) simpleValue.setPropertyRefColumn( propertyRefNode.getValue() );
 	}
 
 	private static void bindSimpleValueType(Element node, SimpleValue simpleValue, Mappings mappings)
Index: src/org/hibernate/mapping/SimpleValue.java
===================================================================
--- src/org/hibernate/mapping/SimpleValue.java	(revision 10864)
+++ src/org/hibernate/mapping/SimpleValue.java	(working copy)
@@ -34,6 +34,7 @@
 	private boolean alternateUniqueKey;
 	private Properties typeParameters;
 	private boolean cascadeDeleteEnabled;
+	private String propertyRefColumn;
 
 	public boolean isCascadeDeleteEnabled() {
 		return cascadeDeleteEnabled;
@@ -85,6 +86,14 @@
 		this.table = table;
 	}
 
+	public String getPropertyRefColumn() {
+		return propertyRefColumn;
+	}
+
+	public void setPropertyRefColumn(String propertyRefColumn) {
+		this.propertyRefColumn = propertyRefColumn;
+	}
+
 	public SimpleValue() {}
 
 	public void createForeignKey() throws MappingException {}
Index: src/org/hibernate/mapping/KeyValue.java
===================================================================
--- src/org/hibernate/mapping/KeyValue.java	(revision 10864)
+++ src/org/hibernate/mapping/KeyValue.java	(working copy)
@@ -28,4 +28,6 @@
 			String defaultCatalog, 
 			String defaultSchema, 
 			RootClass rootClass) throws MappingException;
+
+	public String getPropertyRefColumn();
 }
Index: src/org/hibernate/persister/entity/AbstractEntityPersister.java
===================================================================
--- src/org/hibernate/persister/entity/AbstractEntityPersister.java	(revision 10864)
+++ src/org/hibernate/persister/entity/AbstractEntityPersister.java	(working copy)
@@ -59,6 +59,8 @@
 import org.hibernate.loader.entity.UniqueEntityLoader;
 import org.hibernate.mapping.Column;
 import org.hibernate.mapping.Component;
+import org.hibernate.mapping.Join;
+import org.hibernate.mapping.KeyValue;
 import org.hibernate.mapping.PersistentClass;
 import org.hibernate.mapping.Property;
 import org.hibernate.mapping.Selectable;
@@ -112,6 +114,7 @@
 	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 	private final String[] rootTableKeyColumnNames;
+	private final String[] propertyRefColumnNames;
 	private final String[] identifierAliases;
 	private final int identifierColumnSpan;
 	private final String versionColumnName;
@@ -295,6 +298,10 @@
 		return rootTableKeyColumnNames;
 	}
 
+	public String[] getPropertyRefColumnNames() {
+		return propertyRefColumnNames;
+	}
+
 	protected String[] getSQLUpdateByRowIdStrings() {
 		if ( sqlUpdateByRowIdString == null ) {
 			throw new AssertionFailure( "no update by row id" );
@@ -462,6 +469,15 @@
 			i++;
 		}
 
+		// JOINS
+
+		propertyRefColumnNames = new String[persistentClass.getJoinClosureSpan()];
+		int joinCounter = 0;
+		for ( Iterator joinIter = persistentClass.getJoinClosureIterator(); joinIter.hasNext(); ) {
+			Join join = (Join)joinIter.next();
+			propertyRefColumnNames[joinCounter++] = join.getKey().getPropertyRefColumn();
+		}
+
 		// VERSION
 
 		if ( persistentClass.isVersioned() ) {
@@ -2756,7 +2772,11 @@
 	}
 
 	protected JoinFragment createJoin(String name, boolean innerJoin, boolean includeSubclasses) {
-		final String[] idCols = StringHelper.qualify( name, getIdentifierColumnNames() ); //all joins join to the pk of the driving table
+		final String[] idCols = getPropertyRefColumnNames() != null && 
+														getPropertyRefColumnNames().length > 0 && 
+														getPropertyRefColumnNames()[0] != null ?
+			StringHelper.qualify( name, getPropertyRefColumnNames() ) :
+			StringHelper.qualify( name, getIdentifierColumnNames() ); //all joins join to the pk of the driving table
 		final JoinFragment join = getFactory().getDialect().createOuterJoinFragment();
 		final int tableSpan = getSubclassTableSpan();
 		for ( int j = 1; j < tableSpan; j++ ) { //notice that we skip the first table; it is the driving table!
_______________________________________________
hibernate-dev mailing list
hibernate-dev@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/hibernate-dev

Reply via email to