📄 basicentitypersister.java
字号:
} public BasicEntityPersister( final PersistentClass persistentClass, final CacheConcurrencyStrategy cache, final SessionFactoryImplementor factory) throws HibernateException { // moved up from AbstractEntityPersister ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this.factory = factory; this.cache = cache; 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(); // getClassAlias() handles quotes 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 = isLazyAvailable(); int hydrateSpan = entityMetamodel.getPropertySpan(); propertyColumnSpans = new int[hydrateSpan]; propertySubclassNames = new String[hydrateSpan]; propertyColumnAliases = new String[hydrateSpan][]; propertyColumnNames = 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]; Iterator colIter = prop.getColumnIterator(); int k = 0; while ( colIter.hasNext() ) { Selectable thing = ( Selectable ) colIter.next(); colAliases[k] = thing.getAlias( prop.getValue().getTable() ); colNames[k] = thing.getTemplate( factory.getDialect() ); if ( thing.isFormula() ) { foundFormula = true; } k++; } propertyColumnNames[i] = colNames; 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(); propertyIndexes.put( prop.getName(), new Integer( i ) ); 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 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() ); 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( 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() ); } 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 ); subclassPropertyFetchModeClosure = new FetchMode[joinedFetchesList.size()]; iter = joinedFetchesList.iterator(); int 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 int filterCount = persistentClass.getFilterMap() == null ? 0 : persistentClass.getFilterMap().size(); filterNames = new String[filterCount]; filterConditions = new String[filterCount]; if ( filterCount > 0 ) { iter = persistentClass.getFilterMap().entrySet().iterator(); filterCount = 0; while ( iter.hasNext() ) { final Map.Entry entry = ( Map.Entry ) iter.next(); filterNames[filterCount] = ( String ) entry.getKey(); filterConditions[filterCount] = Template.renderWhereStringTemplate( ( String ) entry.getValue(), FilterImpl.MARKER, factory.getDialect() ); filterConditions[filterCount] = StringHelper.replace( filterConditions[filterCount], ":", ":" + filterNames[filterCount] + "." ); filterCount++; } } } 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.getEntityIdentifier( 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 ); } try { Object result = null; PreparedStatement ps = null; ResultSet rs = null; try { final String lazySelect = getSQLLazySelectString(); if (lazySelect!=null) { // null sql means the lazy properties do not map to // columns or formulas (eg. one-to-one associations) ps = session.getBatcher().prepareSelectStatement(lazySelect); getIdentifierType().nullSafeSet( ps, id, 1, session ); rs = ps.executeQuery(); rs.next(); } final Object[] snapshot = entry.getLoadedState(); for ( int j = 0; j < lazyPropertyNames.length; j++ ) { Object propValue = lazyPropertyTypes[j].nullSafeGet( rs, lazyPropertyColumnAliases[j], session, entity ); setPropertyValue( entity, lazyPropertyNumbers[j], propValue, session.getEntityMode() ); snapshot[ lazyPropertyNumbers[j] ] = lazyPropertyTypes[j].deepCopy( propValue, session.getEntityMode(), factory ); if ( fieldName.equals( lazyPropertyNames[j] ) ) result = propValue; } if (rs!=null) rs.close(); } finally { if (ps!=null) session.getBatcher().closeStatement(ps); } log.trace( "done initializing lazy properties" ); return result; } catch ( SQLException sqle ) { throw JDBCExceptionHelper.convert( getFactory().getSQLExceptionConverter(), sqle, "could not initialize lazy properties: " + MessageHelper.infoString( this, id, getFactory() ), getSQLLazySelectString() ); } } public boolean isBatchable() { return optimisticLockMode()==Versioning.OPTIMISTIC_LOCK_NONE || ( !isVersioned() && optimisticLockMode()==Versioning.OPTIMISTIC_LOCK_VERSION ) || getFactory().getSettings().isJdbcBatchVersionedData(); } public Serializable[] getQuerySpaces() { return getPropertySpaces(); } protected Set getLazyProperties() { return lazyProperties; } private String getLockString(LockMode lockMode) { return ( String ) lockers.get( lockMode ); } public boolean isBatchLoadable() { return batchSize > 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -