📄 abstractentitypersister.java
字号:
return getTableHasColumns(); // for objects that came in via update()
}
else {
boolean[] updateability = getPropertyUpdateability();
int[] propertyTableNumbers = getPropertyTableNumbers();
boolean[] tableUpdateNeeded = new boolean[ getTableSpan() ];
for ( int i = 0; i < dirtyProperties.length; i++ ) {
int property = dirtyProperties[i];
int table = propertyTableNumbers[property];
tableUpdateNeeded[table] = tableUpdateNeeded[table] ||
( getPropertyColumnSpan(property) > 0 && updateability[property] );
}
if ( isVersioned() ) {
tableUpdateNeeded[0] = tableUpdateNeeded[0] ||
Versioning.isVersionIncrementRequired( dirtyProperties, hasDirtyCollection, getPropertyVersionability() );
}
return tableUpdateNeeded;
}
}
public boolean hasRowId() {
return rowIdName != null;
}
public AbstractEntityPersister(
final PersistentClass persistentClass,
final CacheConcurrencyStrategy cache,
final SessionFactoryImplementor factory)
throws HibernateException {
// moved up from AbstractEntityPersister ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
this.factory = factory;
this.cache = cache;
isLazyPropertiesCacheable = persistentClass.isLazyPropertiesCacheable();
this.cacheEntryStructure = factory.getSettings().isStructuredCacheEntriesEnabled() ?
(CacheEntryStructure) new StructuredCacheEntry(this) :
(CacheEntryStructure) new UnstructuredCacheEntry();
this.entityMetamodel = new EntityMetamodel( persistentClass, factory );
if ( persistentClass.hasPojoRepresentation() ) {
//TODO: this is currently specific to pojos, but need to be available for all entity-modes
Iterator iter = persistentClass.getSubclassIterator();
while ( iter.hasNext() ) {
PersistentClass pc = ( PersistentClass ) iter.next();
entityNameBySubclass.put( pc.getMappedClass(), pc.getEntityName() );
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int batch = persistentClass.getBatchSize();
if (batch==-1) batch = factory.getSettings().getDefaultBatchFetchSize();
batchSize = batch;
hasSubselectLoadableCollections = persistentClass.hasSubselectLoadableCollections();
propertyMapping = new BasicEntityPropertyMapping( this );
// IDENTIFIER
identifierColumnSpan = persistentClass.getIdentifier().getColumnSpan();
rootTableKeyColumnNames = new String[identifierColumnSpan];
identifierAliases = new String[identifierColumnSpan];
rowIdName = persistentClass.getRootTable().getRowId();
loaderName = persistentClass.getLoaderName();
Iterator iter = persistentClass.getIdentifier().getColumnIterator();
int i = 0;
while ( iter.hasNext() ) {
Column col = ( Column ) iter.next();
rootTableKeyColumnNames[i] = col.getQuotedName( factory.getDialect() );
identifierAliases[i] = col.getAlias( factory.getDialect(), persistentClass.getRootTable() );
i++;
}
// VERSION
if ( persistentClass.isVersioned() ) {
versionColumnName = ( ( Column ) persistentClass.getVersion().getColumnIterator().next() ).getQuotedName( factory.getDialect() );
}
else {
versionColumnName = null;
}
//WHERE STRING
sqlWhereString = persistentClass.getWhere();
sqlWhereStringTemplate = sqlWhereString == null ?
null :
Template.renderWhereStringTemplate( sqlWhereString, factory.getDialect() );
// PROPERTIES
final boolean lazyAvailable = isInstrumented(EntityMode.POJO);
int hydrateSpan = entityMetamodel.getPropertySpan();
propertyColumnSpans = new int[hydrateSpan];
propertySubclassNames = new String[hydrateSpan];
propertyColumnAliases = new String[hydrateSpan][];
propertyColumnNames = new String[hydrateSpan][];
propertyColumnFormulaTemplates = new String[hydrateSpan][];
propertyUniqueness = new boolean[hydrateSpan];
propertySelectable = new boolean[hydrateSpan];
propertyColumnUpdateable = new boolean[hydrateSpan][];
propertyColumnInsertable = new boolean[hydrateSpan][];
HashSet thisClassProperties = new HashSet();
lazyProperties = new HashSet();
ArrayList lazyNames = new ArrayList();
ArrayList lazyNumbers = new ArrayList();
ArrayList lazyTypes = new ArrayList();
ArrayList lazyColAliases = new ArrayList();
iter = persistentClass.getPropertyClosureIterator();
i = 0;
boolean foundFormula = false;
while ( iter.hasNext() ) {
Property prop = ( Property ) iter.next();
thisClassProperties.add( prop );
int span = prop.getColumnSpan();
propertyColumnSpans[i] = span;
propertySubclassNames[i] = prop.getPersistentClass().getEntityName();
String[] colNames = new String[span];
String[] colAliases = new String[span];
String[] templates = new String[span];
Iterator colIter = prop.getColumnIterator();
int k = 0;
while ( colIter.hasNext() ) {
Selectable thing = ( Selectable ) colIter.next();
colAliases[k] = thing.getAlias( factory.getDialect() , prop.getValue().getTable() );
if ( thing.isFormula() ) {
foundFormula = true;
templates[k] = thing.getTemplate( factory.getDialect() );
}
else {
colNames[k] = thing.getTemplate( factory.getDialect() );
}
k++;
}
propertyColumnNames[i] = colNames;
propertyColumnFormulaTemplates[i] = templates;
propertyColumnAliases[i] = colAliases;
if ( lazyAvailable && prop.isLazy() ) {
lazyProperties.add( prop.getName() );
lazyNames.add( prop.getName() );
lazyNumbers.add( new Integer( i ) );
lazyTypes.add( prop.getValue().getType() );
lazyColAliases.add( colAliases );
}
propertyColumnUpdateable[i] = prop.getValue().getColumnUpdateability();
propertyColumnInsertable[i] = prop.getValue().getColumnInsertability();
propertySelectable[i] = prop.isSelectable();
propertyUniqueness[i] = prop.getValue().isAlternateUniqueKey();
i++;
}
hasFormulaProperties = foundFormula;
lazyPropertyColumnAliases = ArrayHelper.to2DStringArray( lazyColAliases );
lazyPropertyNames = ArrayHelper.toStringArray( lazyNames );
lazyPropertyNumbers = ArrayHelper.toIntArray( lazyNumbers );
lazyPropertyTypes = ArrayHelper.toTypeArray( lazyTypes );
// SUBCLASS PROPERTY CLOSURE
ArrayList columns = new ArrayList();
ArrayList columnsLazy = new ArrayList();
ArrayList aliases = new ArrayList();
ArrayList formulas = new ArrayList();
ArrayList formulaAliases = new ArrayList();
ArrayList formulaTemplates = new ArrayList();
ArrayList formulasLazy = new ArrayList();
ArrayList types = new ArrayList();
ArrayList names = new ArrayList();
ArrayList classes = new ArrayList();
ArrayList templates = new ArrayList();
ArrayList propColumns = new ArrayList();
ArrayList joinedFetchesList = new ArrayList();
ArrayList cascades = new ArrayList();
ArrayList definedBySubclass = new ArrayList();
ArrayList propColumnNumbers = new ArrayList();
ArrayList propFormulaNumbers = new ArrayList();
ArrayList columnSelectables = new ArrayList();
ArrayList propNullables = new ArrayList();
iter = persistentClass.getSubclassPropertyClosureIterator();
while ( iter.hasNext() ) {
Property prop = ( Property ) iter.next();
names.add( prop.getName() );
classes.add( prop.getPersistentClass().getEntityName() );
boolean isDefinedBySubclass = !thisClassProperties.contains( prop );
definedBySubclass.add( new Boolean(isDefinedBySubclass) );
propNullables.add( new Boolean( prop.isOptional() || isDefinedBySubclass) ); //TODO: is this completely correct?
types.add( prop.getType() );
Iterator colIter = prop.getColumnIterator();
String[] cols = new String[prop.getColumnSpan()];
String[] forms = new String[prop.getColumnSpan()];
int[] colnos = new int[prop.getColumnSpan()];
int[] formnos = new int[prop.getColumnSpan()];
int l = 0;
Boolean lazy = new Boolean( prop.isLazy() && lazyAvailable );
while ( colIter.hasNext() ) {
Selectable thing = ( Selectable ) colIter.next();
if ( thing.isFormula() ) {
String template = thing.getTemplate( factory.getDialect() );
formnos[l] = formulaTemplates.size();
colnos[l] = -1;
formulaTemplates.add( template );
forms[l] = template;
formulas.add( thing.getText( factory.getDialect() ) );
formulaAliases.add( thing.getAlias( factory.getDialect() ) );
formulasLazy.add( lazy );
}
else {
String colName = thing.getTemplate( factory.getDialect() );
colnos[l] = columns.size(); //before add :-)
formnos[l] = -1;
columns.add( colName );
cols[l] = colName;
aliases.add( thing.getAlias( factory.getDialect(), prop.getValue().getTable() ) );
columnsLazy.add( lazy );
columnSelectables.add( new Boolean( prop.isSelectable() ) );
}
l++;
}
propColumns.add( cols );
templates.add( forms );
propColumnNumbers.add( colnos );
propFormulaNumbers.add( formnos );
joinedFetchesList.add( prop.getValue().getFetchMode() );
cascades.add( prop.getCascadeStyle() );
}
subclassColumnClosure = ArrayHelper.toStringArray( columns );
subclassColumnAliasClosure = ArrayHelper.toStringArray( aliases );
subclassColumnLazyClosure = ArrayHelper.toBooleanArray( columnsLazy );
subclassColumnSelectableClosure = ArrayHelper.toBooleanArray( columnSelectables );
subclassFormulaClosure = ArrayHelper.toStringArray( formulas );
subclassFormulaTemplateClosure = ArrayHelper.toStringArray( formulaTemplates );
subclassFormulaAliasClosure = ArrayHelper.toStringArray( formulaAliases );
subclassFormulaLazyClosure = ArrayHelper.toBooleanArray( formulasLazy );
subclassPropertyNameClosure = ArrayHelper.toStringArray( names );
subclassPropertySubclassNameClosure = ArrayHelper.toStringArray( classes );
subclassPropertyTypeClosure = ArrayHelper.toTypeArray( types );
subclassPropertyNullabilityClosure = ArrayHelper.toBooleanArray( propNullables );
subclassPropertyFormulaTemplateClosure = ArrayHelper.to2DStringArray( templates );
subclassPropertyColumnNameClosure = ArrayHelper.to2DStringArray( propColumns );
subclassPropertyColumnNumberClosure = ArrayHelper.to2DIntArray( propColumnNumbers );
subclassPropertyFormulaNumberClosure = ArrayHelper.to2DIntArray( propFormulaNumbers );
subclassPropertyCascadeStyleClosure = new CascadeStyle[cascades.size()];
iter = cascades.iterator();
int j = 0;
while ( iter.hasNext() ) subclassPropertyCascadeStyleClosure[j++] = ( CascadeStyle ) iter.next();
subclassPropertyFetchModeClosure = new FetchMode[joinedFetchesList.size()];
iter = joinedFetchesList.iterator();
j = 0;
while ( iter.hasNext() ) subclassPropertyFetchModeClosure[j++] = ( FetchMode ) iter.next();
propertyDefinedOnSubclass = new boolean[definedBySubclass.size()];
iter = definedBySubclass.iterator();
j = 0;
while ( iter.hasNext() ) propertyDefinedOnSubclass[j++] = ( ( Boolean ) iter.next() ).booleanValue();
// Handle any filters applied to the class level
filterHelper = new FilterHelper( persistentClass.getFilterMap(), factory.getDialect() );
temporaryIdTableName = persistentClass.getTemporaryIdTableName();
temporaryIdTableDDL = persistentClass.getTemporaryIdTableDDL();
}
protected String generateLazySelectString() {
if ( !entityMetamodel.hasLazyProperties() ) return null;
HashSet tableNumbers = new HashSet();
ArrayList columnNumbers = new ArrayList();
ArrayList formulaNumbers = new ArrayList();
for ( int i = 0; i < lazyPropertyNames.length; i++ ) {
// all this only really needs to consider properties
// of this class, not its subclasses, but since we
// are reusing code used for sequential selects, we
// use the subclass closure
int propertyNumber = getSubclassPropertyIndex( lazyPropertyNames[i] );
int tableNumber = getSubclassPropertyTableNumber( propertyNumber );
tableNumbers.add( new Integer( tableNumber ) );
int[] colNumbers = subclassPropertyColumnNumberClosure[propertyNumber];
for ( int j = 0; j < colNumbers.length; j++ ) {
if ( colNumbers[j]!=-1 ) {
columnNumbers.add( new Integer( colNumbers[j] ) );
}
}
int[] formNumbers = subclassPropertyFormulaNumberClosure[propertyNumber];
for ( int j = 0; j < formNumbers.length; j++ ) {
if ( formNumbers[j]!=-1 ) {
formulaNumbers.add( new Integer( formNumbers[j] ) );
}
}
}
if ( columnNumbers.size()==0 && formulaNumbers.size()==0 ) {
// only one-to-one is lazy fetched
return null;
}
return renderSelect( ArrayHelper.toIntArray( tableNumbers ),
ArrayHelper.toIntArray( columnNumbers ),
ArrayHelper.toIntArray( formulaNumbers ) );
}
public Object initializeLazyProperty(String fieldName, Object entity, SessionImplementor session)
throws HibernateException {
final Serializable id = session.getContextEntityIdentifier( entity );
final EntityEntry entry = session.getPersistenceContext().getEntry( entity );
if ( entry == null ) {
throw new HibernateException( "entity is not associated with the session: " + id );
}
if ( log.isTraceEnabled() ) {
log.trace(
"initializing lazy properties of: " +
MessageHelper.infoString( this, id, getFactory() ) +
", field access: " + fieldName
);
}
if ( hasCache() ) {
CacheKey cacheKey = new CacheKey(id, getIdentifierType(), getEntityName(), session.getEntityMode(), getFactory() );
Object ce = getCache().get( cacheKey, session.getTimestamp() );
if (ce!=null) {
CacheEntry cacheEntry = (CacheEntry) getCacheEntryStructure().destructure(ce, factory);
if ( !cacheEntry.areLazyPropertiesUnfetched() ) {
//note early exit here:
return initializeLazyPropertiesFromCache( fieldName, entity, session, entry, cacheEntry );
}
}
}
return initializeLazyPropertiesFromDatastore( fieldName, entity, session, id, entry );
}
private Object initializeLazyPropertiesFromDatastore(
final String fieldName,
final Object entity,
final SessionImplementor session,
final Serializable id,
final EntityEntry entry
) {
if ( !hasLazyProperties() ) {
throw new AssertionFailure("no lazy properties");
}
log.trace("initializing lazy properties from datastore");
try {
Object result = null;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -