[hibernate-commits] Hibernate SVN: r21010 - core/patches/JBOSS_EAP_3_2_4_SP1_CP11_JBPAPP-7822/src/org/hibernate/persister/entity.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Tue Jan 10 04:25:56 EST 2012


Author: stliu
Date: 2012-01-10 04:25:55 -0500 (Tue, 10 Jan 2012)
New Revision: 21010

Modified:
   core/patches/JBOSS_EAP_3_2_4_SP1_CP11_JBPAPP-7822/src/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java
Log:
JBPAPP-7822 Back port of HHH-4250 into JBoss EAP 4.3_CP09

Modified: core/patches/JBOSS_EAP_3_2_4_SP1_CP11_JBPAPP-7822/src/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java
===================================================================
--- core/patches/JBOSS_EAP_3_2_4_SP1_CP11_JBPAPP-7822/src/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java	2012-01-10 08:01:18 UTC (rev 21009)
+++ core/patches/JBOSS_EAP_3_2_4_SP1_CP11_JBPAPP-7822/src/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java	2012-01-10 09:25:55 UTC (rev 21010)
@@ -18,6 +18,7 @@
 import org.hibernate.engine.Versioning;
 import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
 import org.hibernate.mapping.Column;
+import org.hibernate.mapping.Join;
 import org.hibernate.mapping.KeyValue;
 import org.hibernate.mapping.PersistentClass;
 import org.hibernate.mapping.Property;
@@ -65,6 +66,8 @@
 	// subclasses and superclasses of this class
 	private final int[] subclassColumnTableNumberClosure;
 	private final int[] subclassFormulaTableNumberClosure;
+	private final boolean[] subclassTableSequentialSelect;
+	private final boolean[] subclassTableIsLazyClosure;
 
 	// subclass discrimination works by assigning particular
 	// values to certain combinations of null primary key
@@ -135,19 +138,50 @@
 				keyCols[k] = ( (Column) citer.next() ).getQuotedName( factory.getDialect() );
 			}
 			keyColumns.add(keyCols);
-			cascadeDeletes.add( new Boolean( key.isCascadeDeleteEnabled() && factory.getDialect().supportsCascadeDelete() ) );
+			cascadeDeletes.add( key.isCascadeDeleteEnabled() && factory.getDialect().supportsCascadeDelete() );
 		}
+
+		//Span of the tables directly mapped by this entity and super-classes, if any
+		int coreTableSpan = tables.size();
+
+		Iterator joinIter = persistentClass.getJoinClosureIterator();
+		while ( joinIter.hasNext() ) {
+			Join join = (Join) joinIter.next();
+			Table tab = join.getTable();
+			String tabname = tab.getQualifiedName(
+					factory.getDialect(),
+					factory.getSettings().getDefaultCatalogName(),
+					factory.getSettings().getDefaultSchemaName()
+			);
+			tables.add(tabname);
+			KeyValue key = join.getKey();
+			int joinIdColumnSpan = 	key.getColumnSpan();
+			String[] keyCols = new String[joinIdColumnSpan];
+			Iterator citer = key.getColumnIterator();
+			for ( int k=0; k<joinIdColumnSpan; k++ ) {
+				Column column = (Column) citer.next();
+				keyCols[k] = column.getQuotedName( factory.getDialect() );
+			}
+			keyColumns.add(keyCols);
+			cascadeDeletes.add( key.isCascadeDeleteEnabled() && factory.getDialect().supportsCascadeDelete() );
+		}
+
 		naturalOrderTableNames = ArrayHelper.toStringArray(tables);
 		naturalOrderTableKeyColumns = ArrayHelper.to2DStringArray(keyColumns);
 		naturalOrderCascadeDeleteEnabled = ArrayHelper.toBooleanArray(cascadeDeletes);
 
 		ArrayList subtables = new ArrayList();
 		ArrayList isConcretes = new ArrayList();
+		ArrayList isDeferreds = new ArrayList();
+		ArrayList isLazies = new ArrayList();
+
 		keyColumns = new ArrayList();
 		titer = persistentClass.getSubclassTableClosureIterator();
 		while ( titer.hasNext() ) {
 			Table tab = (Table) titer.next();
-			isConcretes.add( new Boolean( persistentClass.isClassOrSuperclassTable(tab) ) );
+			isConcretes.add( persistentClass.isClassOrSuperclassTable(tab) );
+			isDeferreds.add(Boolean.FALSE);
+			isLazies.add(Boolean.FALSE);
 			String tabname = tab.getQualifiedName( 
 					factory.getDialect(), 
 					factory.getSettings().getDefaultCatalogName(), 
@@ -161,23 +195,69 @@
 			}
 			keyColumns.add(key);
 		}
-		subclassTableNameClosure = ArrayHelper.toStringArray(subtables);
-		subclassTableKeyColumnClosure = ArrayHelper.to2DStringArray(keyColumns);
-		isClassOrSuperclassTable = ArrayHelper.toBooleanArray(isConcretes);
 
-		constraintOrderedTableNames = new String[subclassTableNameClosure.length];
-		constraintOrderedKeyColumnNames = new String[subclassTableNameClosure.length][];
+		//Add joins
+		joinIter = persistentClass.getSubclassJoinClosureIterator();
+		while ( joinIter.hasNext() ) {
+			Join join = (Join) joinIter.next();
+
+			Table tab = join.getTable();
+
+			isConcretes.add( new Boolean( persistentClass.isClassOrSuperclassTable(tab) ) );
+			isDeferreds.add( new Boolean( join.isSequentialSelect() ) );
+			isLazies.add(new Boolean(join.isLazy()));
+
+			String tabname = tab.getQualifiedName(
+					factory.getDialect(),
+					factory.getSettings().getDefaultCatalogName(),
+					factory.getSettings().getDefaultSchemaName()
+			);
+			subtables.add(tabname);
+			String[] key = new String[idColumnSpan];
+			Iterator citer = tab.getPrimaryKey().getColumnIterator();
+			for ( int k=0; k<idColumnSpan; k++ ) {
+				key[k] = ( (Column) citer.next() ).getQuotedName( factory.getDialect() );
+			}
+			keyColumns.add(key);
+
+		}
+
+		String[] naturalOrderSubclassTableNameClosure = ArrayHelper.toStringArray( subtables );
+		String[][] naturalOrderSubclassTableKeyColumnClosure = ArrayHelper.to2DStringArray( keyColumns );
+		isClassOrSuperclassTable = ArrayHelper.toBooleanArray( isConcretes );
+		subclassTableSequentialSelect = ArrayHelper.toBooleanArray( isDeferreds );
+		subclassTableIsLazyClosure = ArrayHelper.toBooleanArray( isLazies );
+
+
+//		subclassTableNameClosure = ArrayHelper.toStringArray(subtables);
+//		subclassTableKeyColumnClosure = ArrayHelper.to2DStringArray(keyColumns);
+//		isClassOrSuperclassTable = ArrayHelper.toBooleanArray(isConcretes);
+
+		constraintOrderedTableNames = new String[naturalOrderSubclassTableNameClosure.length];
+		constraintOrderedKeyColumnNames = new String[naturalOrderSubclassTableNameClosure.length][];
+
 		int currentPosition = 0;
-		for ( int i = subclassTableNameClosure.length - 1; i >= 0 ; i--, currentPosition++ ) {
-			constraintOrderedTableNames[currentPosition] = subclassTableNameClosure[i];
-			constraintOrderedKeyColumnNames[currentPosition] = subclassTableKeyColumnClosure[i];
+		for ( int i = naturalOrderSubclassTableNameClosure.length - 1; i >= 0; i--, currentPosition++ ) {
+			constraintOrderedTableNames[currentPosition] = naturalOrderSubclassTableNameClosure[i];
+			constraintOrderedKeyColumnNames[currentPosition] = naturalOrderSubclassTableKeyColumnClosure[i];
 		}
 
+		/**
+		 * Suppose an entity Client extends Person, mapped to the tables CLIENT and PERSON respectively.
+		 * For the Client entity:
+		 * naturalOrderTableNames -> PERSON, CLIENT; this reflects the sequence in which the tables are
+		 * added to the meta-data when the annotated entities are processed.
+		 * However, in some instances, for example when generating joins, the CLIENT table needs to be
+		 * the first table as it will the driving table.
+		 * tableNames -> CLIENT, PERSON
+		 */
+
+
 		tableSpan = naturalOrderTableNames.length;
-		tableNames = reverse(naturalOrderTableNames);
-		tableKeyColumns = reverse(naturalOrderTableKeyColumns);
-		reverse(subclassTableNameClosure, tableSpan);
-		reverse(subclassTableKeyColumnClosure, tableSpan);
+		tableNames = reverse( naturalOrderTableNames, coreTableSpan );
+		tableKeyColumns = reverse( naturalOrderTableKeyColumns, coreTableSpan );
+		subclassTableNameClosure = reverse( naturalOrderSubclassTableNameClosure, coreTableSpan );
+		subclassTableKeyColumnClosure = reverse( naturalOrderSubclassTableKeyColumnClosure, coreTableSpan );
 
 		spaces = ArrayHelper.join( 
 				tableNames, 
@@ -196,7 +276,7 @@
 		deleteResultCheckStyles = new ExecuteUpdateResultCheckStyle[tableSpan];
 
 		PersistentClass pc = persistentClass;
-		int jk = tableSpan-1;
+		int jk = coreTableSpan-1;
 		while (pc!=null) {
 			customSQLInsert[jk] = pc.getCustomSQLInsert();
 			insertCallable[jk] = customSQLInsert[jk] != null && pc.isCustomInsertCallable();
@@ -219,7 +299,29 @@
 		if ( jk != -1 ) {
 			throw new AssertionFailure( "Tablespan does not match height of joined-subclass hiearchy." );
 		}
+		joinIter = persistentClass.getJoinClosureIterator();
+		int j = coreTableSpan;
+		while ( joinIter.hasNext() ) {
+			Join join = (Join) joinIter.next();
 
+			customSQLInsert[j] = join.getCustomSQLInsert();
+			insertCallable[j] = customSQLInsert[j] != null && join.isCustomInsertCallable();
+			insertResultCheckStyles[j] = join.getCustomSQLInsertCheckStyle() == null
+					? ExecuteUpdateResultCheckStyle.determineDefault( customSQLInsert[j], insertCallable[j] )
+					: join.getCustomSQLInsertCheckStyle();
+			customSQLUpdate[j] = join.getCustomSQLUpdate();
+			updateCallable[j] = customSQLUpdate[j] != null && join.isCustomUpdateCallable();
+			updateResultCheckStyles[j] = join.getCustomSQLUpdateCheckStyle() == null
+					? ExecuteUpdateResultCheckStyle.determineDefault( customSQLUpdate[j], updateCallable[j] )
+					: join.getCustomSQLUpdateCheckStyle();
+			customSQLDelete[j] = join.getCustomSQLDelete();
+			deleteCallable[j] = customSQLDelete[j] != null && join.isCustomDeleteCallable();
+			deleteResultCheckStyles[j] = join.getCustomSQLDeleteCheckStyle() == null
+					? ExecuteUpdateResultCheckStyle.determineDefault( customSQLDelete[j], deleteCallable[j] )
+					: join.getCustomSQLDeleteCheckStyle();
+			j++;
+		}
+
 		// PROPERTIES
 
 		int hydrateSpan = getPropertySpan();
@@ -370,6 +472,9 @@
 		return spaces; // don't need subclass tables, because they can't appear in conditions
 	}
 
+	protected boolean isSubclassTableSequentialSelect(int j) {
+		return subclassTableSequentialSelect[j] && !isClassOrSuperclassTable[j];
+	}
 
 	protected String getTableName(int j) {
 		return naturalOrderTableNames[j];
@@ -423,24 +528,50 @@
 		}
 	}
 
-	private static final String[] reverse(String[] objects) {
-		int len = objects.length;
-		String[] temp = new String[len];
-		for (int i=0; i<len; i++) {
-			temp[i] = objects[len-i-1];
+
+	/**
+	 * Reverse the first n elements of the incoming array
+	 * @param objects
+	 * @param n
+	 * @return New array with the first n elements in reversed order
+	 */
+	private static final String[] reverse(String [] objects, int n) {
+
+		int size = objects.length;
+		String[] temp = new String[size];
+
+		for (int i=0; i<n; i++) {
+			temp[i] = objects[n-i-1];
 		}
+
+		for (int i=n; i < size; i++) {
+			temp[i] =  objects[i];
+		}
+
 		return temp;
 	}
 
-	private static final String[][] reverse(String[][] objects) {
-		int len = objects.length;
-		String[][] temp = new String[len][];
-		for (int i=0; i<len; i++) {
-			temp[i] = objects[len-i-1];
+	/**
+	 * Reverse the first n elements of the incoming array
+	 * @param objects
+	 * @param n
+	 * @return New array with the first n elements in reversed order
+	 */
+	private static final String[][] reverse(String[][] objects, int n) {
+		int size = objects.length;
+		String[][] temp = new String[size][];
+		for (int i=0; i<n; i++) {
+			temp[i] = objects[n-i-1];
 		}
+
+		for (int i=n; i<size; i++) {
+			temp[i] = objects[i];
+		}
+
 		return temp;
 	}
 
+
 	public String fromTableFragment(String alias) {
 		return getTableName() + ' ' + alias;
 	}
@@ -549,6 +680,10 @@
 		return subclassTableNameClosure.length;
 	}
 
+	protected boolean isSubclassTableLazy(int j) {
+		return subclassTableIsLazyClosure[j];
+	}
+
 	protected boolean isClassOrSuperclassTable(int j) {
 		return isClassOrSuperclassTable[j];
 	}



More information about the hibernate-commits mailing list