1 package org.hibernate.persister.entity; 3 4 import java.io.Serializable ; 5 import java.util.ArrayList ; 6 import java.util.HashMap ; 7 import java.util.HashSet ; 8 import java.util.Iterator ; 9 import java.util.Map ; 10 11 import org.hibernate.EntityMode; 12 import org.hibernate.HibernateException; 13 import org.hibernate.MappingException; 14 import org.hibernate.cache.CacheConcurrencyStrategy; 15 import org.hibernate.engine.Mapping; 16 import org.hibernate.engine.SessionFactoryImplementor; 17 import org.hibernate.mapping.Column; 18 import org.hibernate.mapping.Formula; 19 import org.hibernate.mapping.Join; 20 import org.hibernate.mapping.PersistentClass; 21 import org.hibernate.mapping.Property; 22 import org.hibernate.mapping.Selectable; 23 import org.hibernate.mapping.Subclass; 24 import org.hibernate.mapping.Table; 25 import org.hibernate.mapping.Value; 26 import org.hibernate.sql.InFragment; 27 import org.hibernate.sql.Insert; 28 import org.hibernate.sql.SelectFragment; 29 import org.hibernate.type.AssociationType; 30 import org.hibernate.type.DiscriminatorType; 31 import org.hibernate.type.Type; 32 import org.hibernate.util.ArrayHelper; 33 import org.hibernate.util.MarkerObject; 34 35 44 public class SingleTableEntityPersister extends BasicEntityPersister { 45 46 private final int joinSpan; 48 private final String [] qualifiedTableNames; 49 private final boolean[] isInverseTable; 50 private final boolean[] isNullableTable; 51 private final String [][] keyColumnNames; 52 private final boolean[] cascadeDeleteEnabled; 53 private final boolean hasSequentialSelects; 54 55 private final String [] spaces; 56 57 private final String [] subclassClosure; 58 59 private final String [] subclassTableNameClosure; 60 private final boolean[] subclassTableIsLazyClosure; 61 private final boolean[] isInverseSubclassTable; 62 private final boolean[] isNullableSubclassTable; 63 private final boolean[] subclassTableSequentialSelect; 64 private final String [][] subclassTableKeyColumnClosure; 65 private final boolean[] isClassOrSuperclassTable; 66 67 private final int[] propertyTableNumbers; 69 70 private final int[] subclassPropertyTableNumberClosure; 73 74 private final int[] subclassColumnTableNumberClosure; 75 private final int[] subclassFormulaTableNumberClosure; 76 77 private final Map subclassesByDiscriminatorValue = new HashMap (); 79 private final boolean forceDiscriminator; 80 private final String discriminatorColumnName; 81 private final String discriminatorFormula; 82 private final String discriminatorFormulaTemplate; 83 private final String discriminatorAlias; 84 private final Type discriminatorType; 85 private final String discriminatorSQLValue; 86 private final boolean discriminatorInsertable; 87 88 private final String [] constraintOrderedTableNames; 89 private final String [][] constraintOrderedKeyColumnNames; 90 91 private final Map propertyTableNumbersByNameAndSubclass = new HashMap (); 93 94 private final Map sequentialSelectStringsByEntityName = new HashMap (); 95 96 private static final Object NULL_DISCRIMINATOR = new MarkerObject("<null discriminator>"); 97 private static final Object NOT_NULL_DISCRIMINATOR = new MarkerObject("<not null discriminator>"); 98 99 101 public SingleTableEntityPersister( 102 final PersistentClass persistentClass, 103 final CacheConcurrencyStrategy cache, 104 final SessionFactoryImplementor factory, 105 final Mapping mapping) 106 throws HibernateException { 107 108 super(persistentClass, cache, factory); 109 110 112 joinSpan = persistentClass.getJoinClosureSpan()+1; 113 qualifiedTableNames = new String [joinSpan]; 114 isInverseTable = new boolean[joinSpan]; 115 isNullableTable = new boolean[joinSpan]; 116 keyColumnNames = new String [joinSpan][]; 117 final Table table = persistentClass.getRootTable(); 118 qualifiedTableNames[0] = table.getQualifiedName( 119 factory.getDialect(), 120 factory.getSettings().getDefaultCatalogName(), 121 factory.getSettings().getDefaultSchemaName() 122 ); 123 isInverseTable[0] = false; 124 isNullableTable[0] = false; 125 keyColumnNames[0] = getIdentifierColumnNames(); 126 cascadeDeleteEnabled = new boolean[joinSpan]; 127 128 customSQLInsert = new String [joinSpan]; 130 customSQLUpdate = new String [joinSpan]; 131 customSQLDelete = new String [joinSpan]; 132 insertCallable = new boolean[joinSpan]; 133 updateCallable = new boolean[joinSpan]; 134 deleteCallable = new boolean[joinSpan]; 135 customSQLInsert[0] = persistentClass.getCustomSQLInsert(); 136 customSQLUpdate[0] = persistentClass.getCustomSQLUpdate(); 137 customSQLDelete[0] = persistentClass.getCustomSQLDelete(); 138 insertCallable[0] = persistentClass.isCustomInsertCallable(); 139 updateCallable[0] = persistentClass.isCustomUpdateCallable(); 140 deleteCallable[0] = persistentClass.isCustomDeleteCallable(); 141 142 144 Iterator joinIter = persistentClass.getJoinClosureIterator(); 145 int j=1; 146 while ( joinIter.hasNext() ) { 147 Join join = (Join) joinIter.next(); 148 qualifiedTableNames[j] = join.getTable().getQualifiedName( 149 factory.getDialect(), 150 factory.getSettings().getDefaultCatalogName(), 151 factory.getSettings().getDefaultSchemaName() 152 ); 153 isInverseTable[j] = join.isInverse(); 154 isNullableTable[j] = join.isOptional(); 155 cascadeDeleteEnabled[j] = join.getKey().isCascadeDeleteEnabled() && 156 factory.getDialect().supportsCascadeDelete(); 157 158 customSQLInsert[j] = join.getCustomSQLInsert(); 159 customSQLUpdate[j] = join.getCustomSQLUpdate(); 160 customSQLDelete[j] = join.getCustomSQLDelete(); 161 insertCallable[j] = join.isCustomInsertCallable(); 162 updateCallable[j] = join.isCustomUpdateCallable(); 163 deleteCallable[j] = join.isCustomDeleteCallable(); 164 165 Iterator iter = join.getKey().getColumnIterator(); 166 keyColumnNames[j] = new String [ join.getKey().getColumnSpan() ]; 167 int i = 0; 168 while ( iter.hasNext() ) { 169 Column col = (Column) iter.next(); 170 keyColumnNames[j][i++] = col.getQuotedName( factory.getDialect() ); 171 } 172 173 j++; 174 } 175 176 constraintOrderedTableNames = new String [qualifiedTableNames.length]; 177 constraintOrderedKeyColumnNames = new String [qualifiedTableNames.length][]; 178 for ( int i = qualifiedTableNames.length - 1, position = 0; i >= 0; i--, position++ ) { 179 constraintOrderedTableNames[position] = qualifiedTableNames[i]; 180 constraintOrderedKeyColumnNames[position] = keyColumnNames[i]; 181 } 182 183 spaces = ArrayHelper.join( 184 qualifiedTableNames, 185 ArrayHelper.toStringArray( persistentClass.getSynchronizedTables() ) 186 ); 187 188 final boolean lazyAvailable = isInstrumented(EntityMode.POJO); 189 190 boolean hasDeferred = false; 191 ArrayList subclassTables = new ArrayList (); 192 ArrayList joinKeyColumns = new ArrayList (); 193 ArrayList isConcretes = new ArrayList (); 194 ArrayList isDeferreds = new ArrayList (); 195 ArrayList isInverses = new ArrayList (); 196 ArrayList isNullables = new ArrayList (); 197 ArrayList isLazies = new ArrayList (); 198 subclassTables.add( qualifiedTableNames[0] ); 199 joinKeyColumns.add( getIdentifierColumnNames() ); 200 isConcretes.add(Boolean.TRUE); 201 isDeferreds.add(Boolean.FALSE); 202 isInverses.add(Boolean.FALSE); 203 isNullables.add(Boolean.FALSE); 204 isLazies.add(Boolean.FALSE); 205 joinIter = persistentClass.getSubclassJoinClosureIterator(); 206 while ( joinIter.hasNext() ) { 207 Join join = (Join) joinIter.next(); 208 isConcretes.add( new Boolean ( persistentClass.isClassOrSuperclassJoin(join) ) ); 209 isDeferreds.add( new Boolean ( join.isSequentialSelect() ) ); 210 isInverses.add( new Boolean ( join.isInverse() ) ); 211 isNullables.add( new Boolean ( join.isOptional() ) ); 212 isLazies.add( new Boolean ( lazyAvailable && join.isLazy() ) ); 213 if ( join.isSequentialSelect() && !persistentClass.isClassOrSuperclassJoin(join) ) hasDeferred = true; 214 subclassTables.add( join.getTable().getQualifiedName( 215 factory.getDialect(), 216 factory.getSettings().getDefaultCatalogName(), 217 factory.getSettings().getDefaultSchemaName() 218 ) ); 219 Iterator iter = join.getKey().getColumnIterator(); 220 String [] keyCols = new String [ join.getKey().getColumnSpan() ]; 221 int i = 0; 222 while ( iter.hasNext() ) { 223 Column col = (Column) iter.next(); 224 keyCols[i++] = col.getQuotedName( factory.getDialect() ); 225 } 226 joinKeyColumns.add(keyCols); 227 } 228 229 subclassTableSequentialSelect = ArrayHelper.toBooleanArray(isDeferreds); 230 subclassTableNameClosure = ArrayHelper.toStringArray(subclassTables); 231 subclassTableIsLazyClosure = ArrayHelper.toBooleanArray(isLazies); 232 subclassTableKeyColumnClosure = ArrayHelper.to2DStringArray(joinKeyColumns); 233 isClassOrSuperclassTable = ArrayHelper.toBooleanArray(isConcretes); 234 isInverseSubclassTable = ArrayHelper.toBooleanArray(isInverses); 235 isNullableSubclassTable = ArrayHelper.toBooleanArray(isNullables); 236 hasSequentialSelects = hasDeferred; 237 238 240 final Object discriminatorValue; 241 if ( persistentClass.isPolymorphic() ) { 242 Value discrimValue = persistentClass.getDiscriminator(); 243 if (discrimValue==null) { 244 throw new MappingException("discriminator mapping required for single table polymorphic persistence"); 245 } 246 forceDiscriminator = persistentClass.isForceDiscriminator(); 247 Selectable selectable = (Selectable) discrimValue.getColumnIterator().next(); 248 if ( discrimValue.hasFormula() ) { 249 Formula formula = (Formula) selectable; 250 discriminatorFormula = formula.getFormula(); 251 discriminatorFormulaTemplate = formula.getTemplate( factory.getDialect() ); 252 discriminatorColumnName = null; 253 discriminatorAlias = "clazz_"; 254 } 255 else { 256 Column column = (Column) selectable; 257 discriminatorColumnName = column.getQuotedName( factory.getDialect() ); 258 discriminatorAlias = column.getAlias( factory.getDialect(), persistentClass.getRootTable() ); 259 discriminatorFormula = null; 260 discriminatorFormulaTemplate = null; 261 } 262 discriminatorType = persistentClass.getDiscriminator().getType(); 263 if ( persistentClass.isDiscriminatorValueNull() ) { 264 discriminatorValue = NULL_DISCRIMINATOR; 265 discriminatorSQLValue = InFragment.NULL; 266 discriminatorInsertable = false; 267 } 268 else if ( persistentClass.isDiscriminatorValueNotNull() ) { 269 discriminatorValue = NOT_NULL_DISCRIMINATOR; 270 discriminatorSQLValue = InFragment.NOT_NULL; 271 discriminatorInsertable = false; 272 } 273 else { 274 discriminatorInsertable = persistentClass.isDiscriminatorInsertable() && !discrimValue.hasFormula(); 275 try { 276 DiscriminatorType dtype = (DiscriminatorType) discriminatorType; 277 discriminatorValue = dtype.stringToObject( persistentClass.getDiscriminatorValue() ); 278 discriminatorSQLValue = dtype.objectToSQLString(discriminatorValue); 279 } 280 catch (ClassCastException cce) { 281 throw new MappingException("Illegal discriminator type: " + discriminatorType.getName() ); 282 } 283 catch (Exception e) { 284 throw new MappingException("Could not format discriminator value to SQL string", e); 285 } 286 } 287 } 288 else { 289 forceDiscriminator = false; 290 discriminatorInsertable = false; 291 discriminatorColumnName = null; 292 discriminatorAlias = null; 293 discriminatorType = null; 294 discriminatorValue = null; 295 discriminatorSQLValue = null; 296 discriminatorFormula = null; 297 discriminatorFormulaTemplate = null; 298 } 299 300 302 propertyTableNumbers = new int[ getPropertySpan() ]; 303 Iterator iter = persistentClass.getPropertyClosureIterator(); 304 int i=0; 305 while( iter.hasNext() ) { 306 Property prop = (Property) iter.next(); 307 propertyTableNumbers[i++] = persistentClass.getJoinNumber(prop); 308 309 } 310 311 313 ArrayList columnJoinNumbers = new ArrayList (); 314 ArrayList formulaJoinedNumbers = new ArrayList (); 315 ArrayList propertyJoinNumbers = new ArrayList (); 316 317 iter = persistentClass.getSubclassPropertyClosureIterator(); 318 while ( iter.hasNext() ) { 319 Property prop = (Property) iter.next(); 320 Integer join = new Integer ( persistentClass.getJoinNumber(prop) ); 321 propertyJoinNumbers.add(join); 322 323 propertyTableNumbersByNameAndSubclass.put( 325 prop.getPersistentClass().getEntityName() + '.' + prop.getName(), 326 join 327 ); 328 329 Iterator citer = prop.getColumnIterator(); 330 while ( citer.hasNext() ) { 331 Selectable thing = (Selectable) citer.next(); 332 if ( thing.isFormula() ) { 333 formulaJoinedNumbers.add(join); 334 } 335 else { 336 columnJoinNumbers.add(join); 337 } 338 } 339 } 340 subclassColumnTableNumberClosure = ArrayHelper.toIntArray(columnJoinNumbers); 341 subclassFormulaTableNumberClosure = ArrayHelper.toIntArray(formulaJoinedNumbers); 342 subclassPropertyTableNumberClosure = ArrayHelper.toIntArray(propertyJoinNumbers); 343 344 int subclassSpan = persistentClass.getSubclassSpan() + 1; 345 subclassClosure = new String [subclassSpan]; 346 subclassClosure[0] = getEntityName(); 347 if ( persistentClass.isPolymorphic() ) { 348 subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() ); 349 } 350 351 if ( persistentClass.isPolymorphic() ) { 353 iter = persistentClass.getSubclassIterator(); 354 int k=1; 355 while ( iter.hasNext() ) { 356 Subclass sc = (Subclass) iter.next(); 357 subclassClosure[k++] = sc.getEntityName(); 358 if ( sc.isDiscriminatorValueNull() ) { 359 subclassesByDiscriminatorValue.put( NULL_DISCRIMINATOR, sc.getEntityName() ); 360 } 361 else if ( sc.isDiscriminatorValueNotNull() ) { 362 subclassesByDiscriminatorValue.put( NOT_NULL_DISCRIMINATOR, sc.getEntityName() ); 363 } 364 else { 365 try { 366 DiscriminatorType dtype = (DiscriminatorType) discriminatorType; 367 subclassesByDiscriminatorValue.put( 368 dtype.stringToObject( sc.getDiscriminatorValue() ), 369 sc.getEntityName() 370 ); 371 } 372 catch (ClassCastException cce) { 373 throw new MappingException("Illegal discriminator type: " + discriminatorType.getName() ); 374 } 375 catch (Exception e) { 376 throw new MappingException("Error parsing discriminator value", e); 377 } 378 } 379 } 380 } 381 382 initLockers(); 383 384 initSubclassPropertyAliasesMap(persistentClass); 385 386 postConstruct(mapping); 387 388 } 389 390 protected boolean isInverseTable(int j) { 391 return isInverseTable[j]; 392 } 393 394 protected boolean isInverseSubclassTable(int j) { 395 return isInverseSubclassTable[j]; 396 } 397 398 public String getDiscriminatorColumnName() { 399 return discriminatorColumnName; 400 } 401 402 protected String getDiscriminatorAlias() { 403 return discriminatorAlias; 404 } 405 406 protected String getDiscriminatorFormulaTemplate() { 407 return discriminatorFormulaTemplate; 408 } 409 410 public String getTableName() { 411 return qualifiedTableNames[0]; 412 } 413 414 public Type getDiscriminatorType() { 415 return discriminatorType; 416 } 417 418 public String getDiscriminatorSQLValue() { 419 return discriminatorSQLValue; 420 } 421 422 public String [] getSubclassClosure() { 423 return subclassClosure; 424 } 425 426 public String getSubclassForDiscriminatorValue(Object value) { 427 if (value==null) { 428 return (String ) subclassesByDiscriminatorValue.get(NULL_DISCRIMINATOR); 429 } 430 else { 431 String result = (String ) subclassesByDiscriminatorValue.get(value); 432 if (result==null) result = (String ) subclassesByDiscriminatorValue.get(NOT_NULL_DISCRIMINATOR); 433 return result; 434 } 435 } 436 437 public Serializable [] getPropertySpaces() { 438 return spaces; 439 } 440 441 443 protected boolean isDiscriminatorFormula() { 444 return discriminatorColumnName==null; 445 } 446 447 protected String getDiscriminatorFormula() { 448 return discriminatorFormula; 449 } 450 451 protected String getTableName(int j) { 452 return qualifiedTableNames[j]; 453 } 454 455 protected String [] getKeyColumns(int j) { 456 return keyColumnNames[j]; 457 } 458 459 protected boolean isTableCascadeDeleteEnabled(int j) { 460 return cascadeDeleteEnabled[j]; 461 } 462 463 protected boolean isPropertyOfTable(int property, int j) { 464 return propertyTableNumbers[property]==j; 465 } 466 467 protected boolean isSubclassTableSequentialSelect(int j) { 468 return subclassTableSequentialSelect[j] && !isClassOrSuperclassTable[j]; 469 } 470 471 473 public String fromTableFragment(String name) { 474 return getTableName() + ' ' + name; 475 } 476 477 public String filterFragment(String alias) throws MappingException { 478 String result = discriminatorFilterFragment(alias); 479 if ( hasWhere() ) result += " and " + getSQLWhereString(alias); 480 return result; 481 } 482 483 public String oneToManyFilterFragment(String alias) throws MappingException { 484 return forceDiscriminator ? 485 discriminatorFilterFragment(alias) : 486 ""; 487 } 488 489 private String discriminatorFilterFragment(String alias) throws MappingException { 490 if ( needsDiscriminator() ) { 491 InFragment frag = new InFragment(); 492 493 if ( isDiscriminatorFormula() ) { 494 frag.setFormula( alias, getDiscriminatorFormulaTemplate() ); 495 } 496 else { 497 frag.setColumn( alias, getDiscriminatorColumnName() ); 498 } 499 500 String [] subclasses = getSubclassClosure(); 501 for ( int i=0; i<subclasses.length; i++ ) { 502 final Queryable queryable = (Queryable) getFactory().getEntityPersister( subclasses[i] ); 503 if ( !queryable.isAbstract() ) frag.addValue( queryable.getDiscriminatorSQLValue() ); 504 } 505 506 StringBuffer buf = new StringBuffer (50) 507 .append(" and ") 508 .append( frag.toFragmentString() ); 509 510 return buf.toString(); 511 } 512 else { 513 return ""; 514 } 515 } 516 517 private boolean needsDiscriminator() { 518 return forceDiscriminator || isInherited(); 519 } 520 521 public String getSubclassPropertyTableName(int i) { 522 return subclassTableNameClosure[ subclassPropertyTableNumberClosure[i] ]; 523 } 524 525 protected void addDiscriminatorToSelect(SelectFragment select, String name, String suffix) { 526 if ( isDiscriminatorFormula() ) { 527 select.addFormula( name, getDiscriminatorFormulaTemplate(), getDiscriminatorAlias() ); 528 } 529 else { 530 select.addColumn( name, getDiscriminatorColumnName(), getDiscriminatorAlias() ); 531 } 532 } 533 534 protected int[] getPropertyTableNumbersInSelect() { 535 return propertyTableNumbers; 536 } 537 538 protected int getSubclassPropertyTableNumber(int i) { 539 return subclassPropertyTableNumberClosure[i]; 540 } 541 542 public int getTableSpan() { 543 return joinSpan; 544 } 545 546 protected void addDiscriminatorToInsert(Insert insert) { 547 548 if (discriminatorInsertable) { 549 insert.addColumn( getDiscriminatorColumnName(), discriminatorSQLValue ); 550 } 551 552 } 553 554 protected int[] getSubclassColumnTableNumberClosure() { 555 return subclassColumnTableNumberClosure; 556 } 557 558 protected int[] getSubclassFormulaTableNumberClosure() { 559 return subclassFormulaTableNumberClosure; 560 } 561 562 protected int[] getPropertyTableNumbers() { 563 return propertyTableNumbers; 564 } 565 566 protected boolean isSubclassPropertyDeferred(String propertyName, String entityName) { 567 return hasSequentialSelects && 568 isSubclassTableSequentialSelect( getSubclassPropertyTableNumber(propertyName, entityName) ); 569 } 570 571 public boolean hasSequentialSelect() { 572 return hasSequentialSelects; 573 } 574 575 private int getSubclassPropertyTableNumber(String propertyName, String entityName) { 576 Type type = propertyMapping.toType(propertyName); 577 if ( type.isAssociationType() && ( (AssociationType) type ).useLHSPrimaryKey() ) return 0; 578 final Integer tabnum = (Integer ) propertyTableNumbersByNameAndSubclass.get(entityName + '.' + propertyName); 579 return tabnum==null ? 0 : tabnum.intValue(); 580 } 581 582 protected String getSequentialSelect(String entityName) { 583 return (String ) sequentialSelectStringsByEntityName.get(entityName); 584 } 585 586 private String generateSequentialSelect(Loadable persister) { 587 589 592 BasicEntityPersister subclassPersister = (BasicEntityPersister) persister; 594 HashSet tableNumbers = new HashSet (); 595 String [] props = subclassPersister.getPropertyNames(); 596 String [] classes = subclassPersister.getPropertySubclassNames(); 597 for ( int i=0; i<props.length; i++ ) { 598 int propTableNumber = getSubclassPropertyTableNumber( props[i], classes[i] ); 599 if ( isSubclassTableSequentialSelect(propTableNumber) && !isSubclassTableLazy(propTableNumber) ) { 600 tableNumbers.add( new Integer (propTableNumber) ); 601 } 602 } 603 if ( tableNumbers.isEmpty() ) return null; 604 605 ArrayList columnNumbers = new ArrayList (); 607 final int[] columnTableNumbers = getSubclassColumnTableNumberClosure(); 608 for ( int i=0; i<getSubclassColumnClosure().length; i++ ) { 609 if ( tableNumbers.contains( new Integer ( columnTableNumbers[i] ) ) ) { 610 columnNumbers.add( new Integer (i) ); 611 } 612 } 613 614 ArrayList formulaNumbers = new ArrayList (); 616 final int[] formulaTableNumbers = getSubclassColumnTableNumberClosure(); 617 for ( int i=0; i<getSubclassFormulaTemplateClosure().length; i++ ) { 618 if ( tableNumbers.contains( new Integer ( formulaTableNumbers[i] ) ) ) { 619 formulaNumbers.add( new Integer (i) ); 620 } 621 } 622 623 return renderSelect( 625 ArrayHelper.toIntArray(tableNumbers), 626 ArrayHelper.toIntArray(columnNumbers), 627 ArrayHelper.toIntArray(formulaNumbers) 628 ); 629 } 630 631 632 protected String [] getSubclassTableKeyColumns(int j) { 633 return subclassTableKeyColumnClosure[j]; 634 } 635 636 public String getSubclassTableName(int j) { 637 return subclassTableNameClosure[j]; 638 } 639 640 public int getSubclassTableSpan() { 641 return subclassTableNameClosure.length; 642 } 643 644 protected boolean isClassOrSuperclassTable(int j) { 645 return isClassOrSuperclassTable[j]; 646 } 647 648 protected boolean isSubclassTableLazy(int j) { 649 return subclassTableIsLazyClosure[j]; 650 } 651 652 protected boolean isNullableTable(int j) { 653 return isNullableTable[j]; 654 } 655 656 protected boolean isNullableSubclassTable(int j) { 657 return isNullableSubclassTable[j]; 658 } 659 660 public String getPropertyTableName(String propertyName) { 661 Integer index = getEntityMetamodel().getPropertyIndexOrNull(propertyName); 662 if (index==null) return null; 663 return qualifiedTableNames[ propertyTableNumbers[ index.intValue() ] ]; 664 } 665 666 public void postInstantiate() { 667 super.postInstantiate(); 668 if (hasSequentialSelects) { 669 String [] entityNames = getSubclassClosure(); 670 for ( int i=1; i<entityNames.length; i++ ) { 671 Loadable loadable = (Loadable) getFactory().getEntityPersister( entityNames[i] ); 672 if ( !loadable.isAbstract() ) { String sequentialSelect = generateSequentialSelect(loadable); 674 sequentialSelectStringsByEntityName.put( entityNames[i], sequentialSelect ); 675 } 676 } 677 } 678 } 679 680 public boolean isMultiTable() { 681 return getTableSpan() > 1; 682 } 683 684 public String [] getConstraintOrderedTableNameClosure() { 685 return constraintOrderedTableNames; 686 } 687 688 public String [][] getContraintOrderedTableKeyColumnClosure() { 689 return constraintOrderedKeyColumnNames; 690 } 691 } 692 | Popular Tags |