| 1 package org.hibernate.persister.entity; 3 4 import java.io.Serializable ; 5 import java.sql.CallableStatement ; 6 import java.sql.PreparedStatement ; 7 import java.sql.ResultSet ; 8 import java.sql.SQLException ; 9 import java.sql.Types ; 10 import java.util.ArrayList ; 11 import java.util.Arrays ; 12 import java.util.HashMap ; 13 import java.util.HashSet ; 14 import java.util.Iterator ; 15 import java.util.Map ; 16 import java.util.Set ; 17 18 import net.sf.cglib.transform.impl.InterceptFieldEnabled; 19 20 import org.apache.commons.logging.Log; 21 import org.apache.commons.logging.LogFactory; 22 import org.hibernate.AssertionFailure; 23 import org.hibernate.EntityMode; 24 import org.hibernate.FetchMode; 25 import org.hibernate.HibernateException; 26 import org.hibernate.LockMode; 27 import org.hibernate.MappingException; 28 import org.hibernate.QueryException; 29 import org.hibernate.StaleObjectStateException; 30 import org.hibernate.cache.CacheConcurrencyStrategy; 31 import org.hibernate.cache.CacheKey; 32 import org.hibernate.cache.entry.CacheEntryStructure; 33 import org.hibernate.cache.entry.StructuredCacheEntry; 34 import org.hibernate.cache.entry.UnstructuredCacheEntry; 35 import org.hibernate.engine.CascadeStyle; 36 import org.hibernate.engine.EntityEntry; 37 import org.hibernate.engine.Mapping; 38 import org.hibernate.engine.SessionFactoryImplementor; 39 import org.hibernate.engine.SessionImplementor; 40 import org.hibernate.engine.Versioning; 41 import org.hibernate.exception.JDBCExceptionHelper; 42 import org.hibernate.id.IdentifierGenerator; 43 import org.hibernate.id.IdentifierGeneratorFactory; 44 import org.hibernate.id.PostInsertIdentifierGenerator; 45 import org.hibernate.id.PostInsertIdentityPersister; 46 import org.hibernate.intercept.FieldInterceptor; 47 import org.hibernate.intercept.LazyPropertyInitializer; 48 import org.hibernate.loader.entity.BatchingEntityLoader; 49 import org.hibernate.loader.entity.EntityLoader; 50 import org.hibernate.loader.entity.UniqueEntityLoader; 51 import org.hibernate.mapping.Column; 52 import org.hibernate.mapping.Component; 53 import org.hibernate.mapping.PersistentClass; 54 import org.hibernate.mapping.Property; 55 import org.hibernate.mapping.Selectable; 56 import org.hibernate.metadata.ClassMetadata; 57 import org.hibernate.pretty.MessageHelper; 58 import org.hibernate.property.BackrefPropertyAccessor; 59 import org.hibernate.sql.Alias; 60 import org.hibernate.sql.Delete; 61 import org.hibernate.sql.Insert; 62 import org.hibernate.sql.JoinFragment; 63 import org.hibernate.sql.Select; 64 import org.hibernate.sql.SelectFragment; 65 import org.hibernate.sql.SimpleSelect; 66 import org.hibernate.sql.Template; 67 import org.hibernate.sql.Update; 68 import org.hibernate.tuple.EntityMetamodel; 69 import org.hibernate.tuple.EntityTuplizer; 70 import org.hibernate.tuple.Tuplizer; 71 import org.hibernate.type.AbstractComponentType; 72 import org.hibernate.type.AssociationType; 73 import org.hibernate.type.EntityType; 74 import org.hibernate.type.Type; 75 import org.hibernate.type.TypeFactory; 76 import org.hibernate.type.VersionType; 77 import org.hibernate.util.ArrayHelper; 78 import org.hibernate.util.CollectionHelper; 79 import org.hibernate.util.FilterHelper; 80 import org.hibernate.util.GetGeneratedKeysHelper; 81 import org.hibernate.util.StringHelper; 82 83 89 public abstract class BasicEntityPersister 90 implements OuterJoinLoadable, Queryable, ClassMetadata, UniqueKeyLoadable, 91 SQLLoadable, LazyPropertyInitializer, PostInsertIdentityPersister { 92 93 private static final Log log = LogFactory.getLog( BasicEntityPersister.class ); 94 95 public static final String ENTITY_CLASS = "class"; 96 97 private final SessionFactoryImplementor factory; 99 private final CacheConcurrencyStrategy cache; 100 private final CacheEntryStructure cacheEntryStructure; 101 private final EntityMetamodel entityMetamodel; 102 private final Map entityNameBySubclass = new HashMap (); 103 105 private final String [] rootTableKeyColumnNames; 106 private final String [] identifierAliases; 107 private final int identifierColumnSpan; 108 private final String versionColumnName; 109 private final boolean hasFormulaProperties; 110 private final int batchSize; 111 private final boolean hasSubselectLoadableCollections; 112 protected final String rowIdName; 113 114 private final Set lazyProperties; 115 116 private final String sqlWhereString; 118 private final String sqlWhereStringTemplate; 119 120 private final int[] propertyColumnSpans; 124 private final String [] propertySubclassNames; 125 private final String [][] propertyColumnAliases; 126 private final String [][] propertyColumnNames; 127 private final String [][] propertyColumnFormulaTemplates; 128 private final boolean[][] propertyColumnUpdateable; 129 private final boolean[][] propertyColumnInsertable; 130 private final boolean[] propertyUniqueness; 131 private final boolean[] propertySelectable; 132 133 private final String [] lazyPropertyNames; 135 private final int[] lazyPropertyNumbers; 136 private final Type[] lazyPropertyTypes; 137 private final String [][] lazyPropertyColumnAliases; 138 139 private final String [] subclassPropertyNameClosure; 141 private final String [] subclassPropertySubclassNameClosure; 142 private final Type[] subclassPropertyTypeClosure; 143 private final String [][] subclassPropertyFormulaTemplateClosure; 144 private final String [][] subclassPropertyColumnNameClosure; 145 private final FetchMode[] subclassPropertyFetchModeClosure; 146 private final boolean[] subclassPropertyNullabilityClosure; 147 private final boolean[] propertyDefinedOnSubclass; 148 private final int[][] subclassPropertyColumnNumberClosure; 149 private final int[][] subclassPropertyFormulaNumberClosure; 150 151 private final String [] subclassColumnClosure; 153 private final boolean[] subclassColumnLazyClosure; 154 private final String [] subclassColumnAliasClosure; 155 private final boolean[] subclassColumnSelectableClosure; 156 private final String [] subclassFormulaClosure; 157 private final String [] subclassFormulaTemplateClosure; 158 private final String [] subclassFormulaAliasClosure; 159 private final boolean[] subclassFormulaLazyClosure; 160 161 private final FilterHelper filterHelper; 163 164 private final Map uniqueKeyLoaders = new HashMap (); 165 private final Map lockers = new HashMap (); 166 private final Map loaders = new HashMap (); 167 168 private String sqlVersionSelectString; 170 private String sqlSnapshotSelectString; 171 private String sqlLazySelectString; 172 173 private String sqlIdentityInsertString; 174 private String sqlUpdateByRowIdString; 175 private String sqlLazyUpdateByRowIdString; 176 177 private String [] sqlDeleteStrings; 178 private String [] sqlInsertStrings; 179 private String [] sqlUpdateStrings; 180 private String [] sqlLazyUpdateStrings; 181 182 protected boolean[] insertCallable; 184 protected boolean[] updateCallable; 185 protected boolean[] deleteCallable; 186 protected String [] customSQLInsert; 187 protected String [] customSQLUpdate; 188 protected String [] customSQLDelete; 189 190 private boolean[] tableHasColumns; 191 192 private final String loaderName; 193 194 private UniqueEntityLoader queryLoader; 195 196 private final String temporaryIdTableName; 197 private final String temporaryIdTableDDL; 198 199 private final Map subclassPropertyAliases = new HashMap (); 200 private final Map subclassPropertyColumnNames = new HashMap (); 201 202 protected final BasicEntityPropertyMapping propertyMapping; 203 204 protected void addDiscriminatorToInsert(Insert insert) {} 205 206 protected void addDiscriminatorToSelect(SelectFragment select, String name, String suffix) {} 207 208 protected abstract int[] getSubclassColumnTableNumberClosure(); 209 210 protected abstract int[] getSubclassFormulaTableNumberClosure(); 211 212 public abstract String getSubclassTableName(int j); 213 214 protected abstract String [] getSubclassTableKeyColumns(int j); 215 216 protected abstract boolean isClassOrSuperclassTable(int j); 217 218 protected abstract int getSubclassTableSpan(); 219 220 protected abstract int getTableSpan(); 221 222 protected abstract boolean isTableCascadeDeleteEnabled(int j); 223 224 protected abstract String getTableName(int j); 225 226 protected abstract String [] getKeyColumns(int j); 227 228 protected abstract boolean isPropertyOfTable(int property, int j); 229 230 protected abstract int[] getPropertyTableNumbersInSelect(); 231 232 protected abstract int[] getPropertyTableNumbers(); 233 234 protected abstract int getSubclassPropertyTableNumber(int i); 235 236 protected abstract String filterFragment(String alias) throws MappingException; 237 238 private static final String DISCRIMINATOR_ALIAS = "clazz_"; 239 240 public String getDiscriminatorColumnName() { 241 return DISCRIMINATOR_ALIAS; 242 } 243 244 protected String getDiscriminatorAlias() { 245 return DISCRIMINATOR_ALIAS; 246 } 247 248 protected String getDiscriminatorFormulaTemplate() { 249 return null; 250 } 251 252 protected boolean isInverseTable(int j) { 253 return false; 254 } 255 256 protected boolean isNullableTable(int j) { 257 return false; 258 } 259 260 protected boolean isNullableSubclassTable(int j) { 261 return false; 262 } 263 264 protected boolean isInverseSubclassTable(int j) { 265 return false; 266 } 267 268 public boolean isSubclassEntityName(String entityName) { 269 return entityMetamodel.getSubclassEntityNames().contains(entityName); 270 } 271 272 private boolean[] getTableHasColumns() { 273 return tableHasColumns; 274 } 275 276 public String [] getRootTableKeyColumnNames() { 277 return rootTableKeyColumnNames; 278 } 279 280 protected String [] getSQLUpdateByRowIdStrings() { 281 if ( sqlUpdateByRowIdString == null ) { 282 throw new AssertionFailure( "no update by row id" ); 283 } 284 String [] result = new String [getTableSpan()]; 285 result[0] = sqlUpdateByRowIdString; 286 for ( int i = 1; i < getTableSpan(); i++ ) result[i] = sqlUpdateStrings[i]; 287 return result; 288 } 289 290 protected String [] getSQLLazyUpdateByRowIdStrings() { 291 if ( sqlLazyUpdateByRowIdString == null ) { 292 throw new AssertionFailure( "no update by row id" ); 293 } 294 String [] result = new String [getTableSpan()]; 295 result[0] = sqlLazyUpdateByRowIdString; 296 for ( int i = 1; i < getTableSpan(); i++ ) result[i] = sqlLazyUpdateStrings[i]; 297 return result; 298 } 299 300 protected String getSQLSnapshotSelectString() { 301 return sqlSnapshotSelectString; 302 } 303 304 protected String getSQLLazySelectString() { 305 return sqlLazySelectString; 306 } 307 308 protected String [] getSQLDeleteStrings() { 309 return sqlDeleteStrings; 310 } 311 312 protected String [] getSQLInsertStrings() { 313 return sqlInsertStrings; 314 } 315 316 protected String [] getSQLUpdateStrings() { 317 return sqlUpdateStrings; 318 } 319 320 protected String [] getSQLLazyUpdateStrings() { 321 return sqlLazyUpdateStrings; 322 } 323 324 327 protected String getSQLIdentityInsertString() { 328 return sqlIdentityInsertString; 329 } 330 331 protected String getVersionSelectString() { 332 return sqlVersionSelectString; 333 } 334 335 protected boolean isInsertCallable(int j) { 336 return insertCallable[j]; 337 } 338 339 protected boolean isUpdateCallable(int j) { 340 return updateCallable[j]; 341 } 342 343 protected boolean isDeleteCallable(int j) { 344 return deleteCallable[j]; 345 } 346 347 protected boolean isSubclassPropertyDeferred(String propertyName, String entityName) { 348 return false; 349 } 350 351 protected boolean isSubclassTableSequentialSelect(int j) { 352 return false; 353 } 354 355 public boolean hasSequentialSelect() { 356 return false; 357 } 358 359 362 protected boolean[] getTableUpdateNeeded(final int[] dirtyProperties, boolean hasDirtyCollection) { 363 364 if ( dirtyProperties == null ) { 365 return getTableHasColumns(); } 367 else { 368 boolean[] updateability = getPropertyUpdateability(); 369 int[] propertyTableNumbers = getPropertyTableNumbers(); 370 boolean[] tableUpdateNeeded = new boolean[ getTableSpan() ]; 371 for ( int i = 0; i < dirtyProperties.length; i++ ) { 372 int property = dirtyProperties[i]; 373 int table = propertyTableNumbers[property]; 374 tableUpdateNeeded[table] = tableUpdateNeeded[table] || 375 ( getPropertyColumnSpan(property) > 0 && updateability[property] ); 376 } 377 if ( isVersioned() ) { 378 tableUpdateNeeded[0] = tableUpdateNeeded[0] || 379 Versioning.isVersionIncrementRequired( dirtyProperties, hasDirtyCollection, getPropertyVersionability() ); 380 } 381 return tableUpdateNeeded; 382 } 383 } 384 385 public boolean hasRowId() { 386 return rowIdName != null; 387 } 388 389 public BasicEntityPersister( 390 final PersistentClass persistentClass, 391 final CacheConcurrencyStrategy cache, 392 final SessionFactoryImplementor factory) 393 throws HibernateException { 394 395 this.factory = factory; 397 this.cache = cache; 398 this.cacheEntryStructure = factory.getSettings().isStructuredCacheEntriesEnabled() ? 399 (CacheEntryStructure) new StructuredCacheEntry(this) : 400 (CacheEntryStructure) new UnstructuredCacheEntry(); 401 402 this.entityMetamodel = new EntityMetamodel( persistentClass, factory ); 403 404 if ( persistentClass.hasPojoRepresentation() ) { 405 Iterator iter = persistentClass.getSubclassIterator(); 407 while ( iter.hasNext() ) { 408 PersistentClass pc = ( PersistentClass ) iter.next(); 409 entityNameBySubclass.put( pc.getMappedClass(), pc.getEntityName() ); 410 } 411 } 412 414 int batch = persistentClass.getBatchSize(); 415 if (batch==-1) batch = factory.getSettings().getDefaultBatchFetchSize(); 416 batchSize = batch; 417 hasSubselectLoadableCollections = persistentClass.hasSubselectLoadableCollections(); 418 419 propertyMapping = new BasicEntityPropertyMapping( this ); 420 421 423 identifierColumnSpan = persistentClass.getIdentifier().getColumnSpan(); 424 rootTableKeyColumnNames = new String [identifierColumnSpan]; 425 identifierAliases = new String [identifierColumnSpan]; 426 427 rowIdName = persistentClass.getRootTable().getRowId(); 428 429 loaderName = persistentClass.getLoaderName(); 430 431 Iterator iter = persistentClass.getIdentifier().getColumnIterator(); 432 int i = 0; 433 while ( iter.hasNext() ) { 434 Column col = ( Column ) iter.next(); 435 rootTableKeyColumnNames[i] = col.getQuotedName( factory.getDialect() ); 436 identifierAliases[i] = col.getAlias( factory.getDialect(), persistentClass.getRootTable() ); 437 i++; 438 } 439 440 442 if ( persistentClass.isVersioned() ) { 443 versionColumnName = ( ( Column ) persistentClass.getVersion().getColumnIterator().next() ).getQuotedName( factory.getDialect() ); 444 } 445 else { 446 versionColumnName = null; 447 } 448 449 451 sqlWhereString = persistentClass.getWhere(); 452 sqlWhereStringTemplate = sqlWhereString == null ? 453 null : 454 Template.renderWhereStringTemplate( sqlWhereString, factory.getDialect() ); 455 456 458 final boolean lazyAvailable = isInstrumented(EntityMode.POJO); 459 460 int hydrateSpan = entityMetamodel.getPropertySpan(); 461 propertyColumnSpans = new int[hydrateSpan]; 462 propertySubclassNames = new String [hydrateSpan]; 463 propertyColumnAliases = new String [hydrateSpan][]; 464 propertyColumnNames = new String [hydrateSpan][]; 465 propertyColumnFormulaTemplates = new String [hydrateSpan][]; 466 propertyUniqueness = new boolean[hydrateSpan]; 467 propertySelectable = new boolean[hydrateSpan]; 468 propertyColumnUpdateable = new boolean[hydrateSpan][]; 469 propertyColumnInsertable = new boolean[hydrateSpan][]; 470 HashSet thisClassProperties = new HashSet (); 471 472 lazyProperties = new HashSet (); 473 ArrayList lazyNames = new ArrayList (); 474 ArrayList lazyNumbers = new ArrayList (); 475 ArrayList lazyTypes = new ArrayList (); 476 ArrayList lazyColAliases = new ArrayList (); 477 478 iter = persistentClass.getPropertyClosureIterator(); 479 i = 0; 480 boolean foundFormula = false; 481 while ( iter.hasNext() ) { 482 Property prop = ( Property ) iter.next(); 483 thisClassProperties.add( prop ); 484 485 int span = prop.getColumnSpan(); 486 propertyColumnSpans[i] = span; 487 propertySubclassNames[i] = prop.getPersistentClass().getEntityName(); 488 String [] colNames = new String [span]; 489 String [] colAliases = new String [span]; 490 String [] templates = new String [span]; 491 Iterator colIter = prop.getColumnIterator(); 492 int k = 0; 493 while ( colIter.hasNext() ) { 494 Selectable thing = ( Selectable ) colIter.next(); 495 colAliases[k] = thing.getAlias( factory.getDialect() , prop.getValue().getTable() ); 496 if ( thing.isFormula() ) { 497 foundFormula = true; 498 templates[k] = thing.getTemplate( factory.getDialect() ); 499 } 500 else { 501 colNames[k] = thing.getTemplate( factory.getDialect() ); 502 } 503 k++; 504 } 505 propertyColumnNames[i] = colNames; 506 propertyColumnFormulaTemplates[i] = templates; 507 propertyColumnAliases[i] = colAliases; 508 509 if ( lazyAvailable && prop.isLazy() ) { 510 lazyProperties.add( prop.getName() ); 511 lazyNames.add( prop.getName() ); 512 lazyNumbers.add( new Integer ( i ) ); 513 lazyTypes.add( prop.getValue().getType() ); 514 lazyColAliases.add( colAliases ); 515 } 516 517 propertyColumnUpdateable[i] = prop.getValue().getColumnUpdateability(); 518 propertyColumnInsertable[i] = prop.getValue().getColumnInsertability(); 519 520 propertySelectable[i] = prop.isSelectable(); 521 522 propertyUniqueness[i] = prop.getValue().isAlternateUniqueKey(); 523 524 i++; 525 526 } 527 hasFormulaProperties = foundFormula; 528 lazyPropertyColumnAliases = ArrayHelper.to2DStringArray( lazyColAliases ); 529 lazyPropertyNames = ArrayHelper.toStringArray( lazyNames ); 530 lazyPropertyNumbers = ArrayHelper.toIntArray( lazyNumbers ); 531 lazyPropertyTypes = ArrayHelper.toTypeArray( lazyTypes ); 532 533 535 ArrayList columns = new ArrayList (); 536 ArrayList columnsLazy = new ArrayList (); 537 ArrayList aliases = new ArrayList (); 538 ArrayList formulas = new ArrayList (); 539 ArrayList formulaAliases = new ArrayList (); 540 ArrayList formulaTemplates = new ArrayList (); 541 ArrayList formulasLazy = new ArrayList (); 542 ArrayList types = new ArrayList (); 543 ArrayList names = new ArrayList (); 544 ArrayList classes = new ArrayList (); 545 ArrayList templates = new ArrayList (); 546 ArrayList propColumns = new ArrayList (); 547 ArrayList joinedFetchesList = new ArrayList (); 548 ArrayList definedBySubclass = new ArrayList (); 549 ArrayList propColumnNumbers = new ArrayList (); 550 ArrayList propFormulaNumbers = new ArrayList (); 551 ArrayList columnSelectables = new ArrayList (); 552 ArrayList propNullables = new ArrayList (); 553 554 iter = persistentClass.getSubclassPropertyClosureIterator(); 555 while ( iter.hasNext() ) { 556 Property prop = ( Property ) iter.next(); 557 names.add( prop.getName() ); 558 classes.add( prop.getPersistentClass().getEntityName() ); 559 boolean isDefinedBySubclass = !thisClassProperties.contains( prop ); 560 definedBySubclass.add( new Boolean (isDefinedBySubclass) ); 561 propNullables.add( new Boolean ( prop.isOptional() || isDefinedBySubclass) ); types.add( prop.getType() ); 563 564 Iterator colIter = prop.getColumnIterator(); 565 String [] cols = new String [prop.getColumnSpan()]; 566 String [] forms = new String [prop.getColumnSpan()]; 567 int[] colnos = new int[prop.getColumnSpan()]; 568 int[] formnos = new int[prop.getColumnSpan()]; 569 int l = 0; 570 Boolean lazy = new Boolean ( prop.isLazy() && lazyAvailable ); 571 while ( colIter.hasNext() ) { 572 Selectable thing = ( Selectable ) colIter.next(); 573 if ( thing.isFormula() ) { 574 String template = thing.getTemplate( factory.getDialect() ); 575 formnos[l] = formulaTemplates.size(); 576 colnos[l] = -1; 577 formulaTemplates.add( template ); 578 forms[l] = template; 579 formulas.add( thing.getText( factory.getDialect() ) ); 580 formulaAliases.add( thing.getAlias( factory.getDialect() ) ); 581 formulasLazy.add( lazy ); 582 } 583 else { 584 String colName = thing.getTemplate( factory.getDialect() ); 585 colnos[l] = columns.size(); formnos[l] = -1; 587 columns.add( colName ); 588 cols[l] = colName; 589 aliases.add( thing.getAlias( factory.getDialect(), prop.getValue().getTable() ) ); 590 columnsLazy.add( lazy ); 591 columnSelectables.add( new Boolean ( prop.isSelectable() ) ); 592 } 593 l++; 594 } 595 propColumns.add( cols ); 596 templates.add( forms ); 597 propColumnNumbers.add( colnos ); 598 propFormulaNumbers.add( formnos ); 599 600 joinedFetchesList.add( prop.getValue().getFetchMode() ); 601 } 602 subclassColumnClosure = ArrayHelper.toStringArray( columns ); 603 subclassColumnAliasClosure = ArrayHelper.toStringArray( aliases ); 604 subclassColumnLazyClosure = ArrayHelper.toBooleanArray( columnsLazy ); 605 subclassColumnSelectableClosure = ArrayHelper.toBooleanArray( columnSelectables ); 606 607 subclassFormulaClosure = ArrayHelper.toStringArray( formulas ); 608 subclassFormulaTemplateClosure = ArrayHelper.toStringArray( formulaTemplates ); 609 subclassFormulaAliasClosure = ArrayHelper.toStringArray( formulaAliases ); 610 subclassFormulaLazyClosure = ArrayHelper.toBooleanArray( formulasLazy ); 611 612 subclassPropertyNameClosure = ArrayHelper.toStringArray( names ); 613 subclassPropertySubclassNameClosure = ArrayHelper.toStringArray( classes ); 614 subclassPropertyTypeClosure = ArrayHelper.toTypeArray( types ); 615 subclassPropertyNullabilityClosure = ArrayHelper.toBooleanArray( propNullables ); 616 subclassPropertyFormulaTemplateClosure = ArrayHelper.to2DStringArray( templates ); 617 subclassPropertyColumnNameClosure = ArrayHelper.to2DStringArray( propColumns ); 618 subclassPropertyColumnNumberClosure = ArrayHelper.to2DIntArray( propColumnNumbers ); 619 subclassPropertyFormulaNumberClosure = ArrayHelper.to2DIntArray( propFormulaNumbers ); 620 621 subclassPropertyFetchModeClosure = new FetchMode[joinedFetchesList.size()]; 622 iter = joinedFetchesList.iterator(); 623 int j = 0; 624 while ( iter.hasNext() ) subclassPropertyFetchModeClosure[j++] = ( FetchMode ) iter.next(); 625 626 propertyDefinedOnSubclass = new boolean[definedBySubclass.size()]; 627 iter = definedBySubclass.iterator(); 628 j = 0; 629 while ( iter.hasNext() ) propertyDefinedOnSubclass[j++] = ( ( Boolean ) iter.next() ).booleanValue(); 630 631 filterHelper = new FilterHelper( persistentClass.getFilterMap(), factory.getDialect() ); 633 634 temporaryIdTableName = persistentClass.getTemporaryIdTableName(); 635 temporaryIdTableDDL = persistentClass.getTemporaryIdTableDDL(); 636 } 637 638 protected String generateLazySelectString() { 639 640 if ( !entityMetamodel.hasLazyProperties() ) return null; 641 642 HashSet tableNumbers = new HashSet (); 643 ArrayList columnNumbers = new ArrayList (); 644 ArrayList formulaNumbers = new ArrayList (); 645 for ( int i = 0; i < lazyPropertyNames.length; i++ ) { 646 int propertyNumber = getSubclassPropertyIndex( lazyPropertyNames[i] ); 651 652 int tableNumber = getSubclassPropertyTableNumber( propertyNumber ); 653 tableNumbers.add( new Integer ( tableNumber ) ); 654 655 int[] colNumbers = subclassPropertyColumnNumberClosure[propertyNumber]; 656 for ( int j = 0; j < colNumbers.length; j++ ) { 657 if ( colNumbers[j]!=-1 ) { 658 columnNumbers.add( new Integer ( colNumbers[j] ) ); 659 } 660 } 661 int[] formNumbers = subclassPropertyFormulaNumberClosure[propertyNumber]; 662 for ( int j = 0; j < formNumbers.length; j++ ) { 663 if ( formNumbers[j]!=-1 ) { 664 formulaNumbers.add( new Integer ( formNumbers[j] ) ); 665 } 666 } 667 } 668 669 |