ArrayList keyColumnReaderTemplates = new ArrayList();
ArrayList cascadeDeletes = new ArrayList();
Iterator titer = persistentClass.getTableClosureIterator();
Iterator kiter = persistentClass.getKeyClosureIterator();
while ( titer.hasNext() ) {
Table tab = (Table) titer.next();
KeyValue key = (KeyValue) kiter.next();
String tabname = tab.getQualifiedName(
factory.getDialect(),
factory.getSettings().getDefaultCatalogName(),
factory.getSettings().getDefaultSchemaName()
);
tables.add(tabname);
String[] keyCols = new String[idColumnSpan];
String[] keyColReaders = new String[idColumnSpan];
String[] keyColReaderTemplates = new String[idColumnSpan];
Iterator citer = key.getColumnIterator();
for ( int k=0; k<idColumnSpan; k++ ) {
Column column = (Column) citer.next();
keyCols[k] = column.getQuotedName( factory.getDialect() );
keyColReaders[k] = column.getReadExpr( factory.getDialect() );
keyColReaderTemplates[k] = column.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() );
}
keyColumns.add(keyCols);
keyColumnReaders.add(keyColReaders);
keyColumnReaderTemplates.add(keyColReaderTemplates);
cascadeDeletes.add( new Boolean( key.isCascadeDeleteEnabled() && factory.getDialect().supportsCascadeDelete() ) );
}
//Span of the tables directly mapped by this entity and super-classes, if any
coreTableSpan = tables.size();
isNullableTable = new boolean[persistentClass.getJoinClosureSpan()];
int tabIndex = 0;
Iterator joinIter = persistentClass.getJoinClosureIterator();
while ( joinIter.hasNext() ) {
Join join = (Join) joinIter.next();
isNullableTable[tabIndex++] = join.isOptional();
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];
String[] keyColReaders = new String[joinIdColumnSpan];
String[] keyColReaderTemplates = 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() );
keyColReaders[k] = column.getReadExpr( factory.getDialect() );
keyColReaderTemplates[k] = column.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() );
}
keyColumns.add(keyCols);
keyColumnReaders.add(keyColReaders);
keyColumnReaderTemplates.add(keyColReaderTemplates);
cascadeDeletes.add( new Boolean( key.isCascadeDeleteEnabled() && factory.getDialect().supportsCascadeDelete() ) );
}
naturalOrderTableNames = ArrayHelper.toStringArray(tables);
naturalOrderTableKeyColumns = ArrayHelper.to2DStringArray(keyColumns);
naturalOrderTableKeyColumnReaders = ArrayHelper.to2DStringArray(keyColumnReaders);
naturalOrderTableKeyColumnReaderTemplates = ArrayHelper.to2DStringArray(keyColumnReaderTemplates);
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) ) );
isDeferreds.add(Boolean.FALSE);
isLazies.add(Boolean.FALSE);
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);
}
//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);
constraintOrderedTableNames = new String[naturalOrderSubclassTableNameClosure.length];
constraintOrderedKeyColumnNames = new String[naturalOrderSubclassTableNameClosure.length][];
int currentPosition = 0;
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, coreTableSpan);
tableKeyColumns = reverse(naturalOrderTableKeyColumns, coreTableSpan);
tableKeyColumnReaders = reverse(naturalOrderTableKeyColumnReaders, coreTableSpan);
tableKeyColumnReaderTemplates = reverse(naturalOrderTableKeyColumnReaderTemplates, coreTableSpan);
subclassTableNameClosure = reverse(naturalOrderSubclassTableNameClosure, coreTableSpan);
subclassTableKeyColumnClosure = reverse(naturalOrderSubclassTableKeyColumnClosure, coreTableSpan);
spaces = ArrayHelper.join(
tableNames,
ArrayHelper.toStringArray( persistentClass.getSynchronizedTables() )
);
// Custom sql
customSQLInsert = new String[tableSpan];
customSQLUpdate = new String[tableSpan];
customSQLDelete = new String[tableSpan];
insertCallable = new boolean[tableSpan];
updateCallable = new boolean[tableSpan];
deleteCallable = new boolean[tableSpan];
insertResultCheckStyles = new ExecuteUpdateResultCheckStyle[tableSpan];
updateResultCheckStyles = new ExecuteUpdateResultCheckStyle[tableSpan];
deleteResultCheckStyles = new ExecuteUpdateResultCheckStyle[tableSpan];
PersistentClass pc = persistentClass;
int jk = coreTableSpan-1;
while (pc!=null) {
customSQLInsert[jk] = pc.getCustomSQLInsert();
insertCallable[jk] = customSQLInsert[jk] != null && pc.isCustomInsertCallable();
insertResultCheckStyles[jk] = pc.getCustomSQLInsertCheckStyle() == null
? ExecuteUpdateResultCheckStyle.determineDefault( customSQLInsert[jk], insertCallable[jk] )
: pc.getCustomSQLInsertCheckStyle();
customSQLUpdate[jk] = pc.getCustomSQLUpdate();
updateCallable[jk] = customSQLUpdate[jk] != null && pc.isCustomUpdateCallable();
updateResultCheckStyles[jk] = pc.getCustomSQLUpdateCheckStyle() == null
? ExecuteUpdateResultCheckStyle.determineDefault( customSQLUpdate[jk], updateCallable[jk] )
: pc.getCustomSQLUpdateCheckStyle();
customSQLDelete[jk] = pc.getCustomSQLDelete();
deleteCallable[jk] = customSQLDelete[jk] != null && pc.isCustomDeleteCallable();
deleteResultCheckStyles[jk] = pc.getCustomSQLDeleteCheckStyle() == null
? ExecuteUpdateResultCheckStyle.determineDefault( customSQLDelete[jk], deleteCallable[jk] )
: pc.getCustomSQLDeleteCheckStyle();
jk--;
pc = pc.getSuperclass();
}
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();
naturalOrderPropertyTableNumbers = new int[hydrateSpan];
propertyTableNumbers = new int[hydrateSpan];
Iterator iter = persistentClass.getPropertyClosureIterator();
int i=0;
while( iter.hasNext() ) {
Property prop = (Property) iter.next();
String tabname = prop.getValue().getTable().getQualifiedName(
factory.getDialect(),
factory.getSettings().getDefaultCatalogName(),
factory.getSettings().getDefaultSchemaName()
);
propertyTableNumbers[i] = getTableId(tabname, tableNames);
naturalOrderPropertyTableNumbers[i] = getTableId(tabname, naturalOrderTableNames);
i++;
}
// subclass closure properties
//TODO: code duplication with SingleTableEntityPersister
ArrayList columnTableNumbers = new ArrayList();
ArrayList formulaTableNumbers = new ArrayList();
ArrayList propTableNumbers = new ArrayList();
iter = persistentClass.getSubclassPropertyClosureIterator();
while ( iter.hasNext() ) {
Property prop = (Property) iter.next();
Table tab = prop.getValue().getTable();
String tabname = tab.getQualifiedName(
factory.getDialect(),
factory.getSettings().getDefaultCatalogName(),
factory.getSettings().getDefaultSchemaName()
);
Integer tabnum = new Integer( getTableId(tabname, subclassTableNameClosure) );