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];
}