📄 abstractcollectionpersister.java
字号:
//$Id: AbstractCollectionPersister.java 11398 2007-04-10 14:54:07Z steve.ebersole@jboss.com $package org.hibernate.persister.collection;import java.io.Serializable;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.Arrays;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.hibernate.AssertionFailure;import org.hibernate.FetchMode;import org.hibernate.HibernateException;import org.hibernate.MappingException;import org.hibernate.QueryException;import org.hibernate.TransientObjectException;import org.hibernate.jdbc.Expectation;import org.hibernate.jdbc.Expectations;import org.hibernate.cache.CacheException;import org.hibernate.cache.access.CollectionRegionAccessStrategy;import org.hibernate.cache.entry.CacheEntryStructure;import org.hibernate.cache.entry.StructuredCollectionCacheEntry;import org.hibernate.cache.entry.StructuredMapCacheEntry;import org.hibernate.cache.entry.UnstructuredCacheEntry;import org.hibernate.cfg.Configuration;import org.hibernate.collection.PersistentCollection;import org.hibernate.dialect.Dialect;import org.hibernate.engine.EntityKey;import org.hibernate.engine.PersistenceContext;import org.hibernate.engine.SessionFactoryImplementor;import org.hibernate.engine.SessionImplementor;import org.hibernate.engine.SubselectFetch;import org.hibernate.engine.ExecuteUpdateResultCheckStyle;import org.hibernate.exception.JDBCExceptionHelper;import org.hibernate.exception.SQLExceptionConverter;import org.hibernate.id.IdentifierGenerator;import org.hibernate.loader.collection.CollectionInitializer;import org.hibernate.mapping.Collection;import org.hibernate.mapping.Column;import org.hibernate.mapping.Formula;import org.hibernate.mapping.IdentifierCollection;import org.hibernate.mapping.IndexedCollection;import org.hibernate.mapping.List;import org.hibernate.mapping.Selectable;import org.hibernate.mapping.Table;import org.hibernate.metadata.CollectionMetadata;import org.hibernate.persister.entity.EntityPersister;import org.hibernate.persister.entity.Loadable;import org.hibernate.persister.entity.PropertyMapping;import org.hibernate.pretty.MessageHelper;import org.hibernate.sql.Alias;import org.hibernate.sql.SelectFragment;import org.hibernate.sql.SimpleSelect;import org.hibernate.sql.Template;import org.hibernate.type.AbstractComponentType;import org.hibernate.type.CollectionType;import org.hibernate.type.EntityType;import org.hibernate.type.Type;import org.hibernate.util.ArrayHelper;import org.hibernate.util.CollectionHelper;import org.hibernate.util.FilterHelper;import org.hibernate.util.StringHelper;/** * Base implementation of the <tt>QueryableCollection</tt> interface. * * @author Gavin King * @see BasicCollectionPersister * @see OneToManyPersister */public abstract class AbstractCollectionPersister implements CollectionMetadata, SQLLoadableCollection { // TODO: encapsulate the protected instance variables! private final String role; //SQL statements private final String sqlDeleteString; private final String sqlInsertRowString; private final String sqlUpdateRowString; private final String sqlDeleteRowString; private final String sqlSelectSizeString; private final String sqlSelectRowByIndexString; private final String sqlDetectRowByIndexString; private final String sqlDetectRowByElementString; private final String sqlOrderByString; protected final String sqlWhereString; private final String sqlOrderByStringTemplate; private final String sqlWhereStringTemplate; private final boolean hasOrder; protected final boolean hasWhere; private final int baseIndex; private final String nodeName; private final String elementNodeName; private final String indexNodeName; protected final boolean indexContainsFormula; protected final boolean elementIsPureFormula; //types private final Type keyType; private final Type indexType; protected final Type elementType; private final Type identifierType; //columns protected final String[] keyColumnNames; protected final String[] indexColumnNames; protected final String[] indexFormulaTemplates; protected final String[] indexFormulas; protected final boolean[] indexColumnIsSettable; protected final String[] elementColumnNames; protected final String[] elementFormulaTemplates; protected final String[] elementFormulas; protected final boolean[] elementColumnIsSettable; protected final boolean[] elementColumnIsInPrimaryKey; protected final String[] indexColumnAliases; protected final String[] elementColumnAliases; protected final String[] keyColumnAliases; protected final String identifierColumnName; private final String identifierColumnAlias; //private final String unquotedIdentifierColumnName; protected final String qualifiedTableName; private final String queryLoaderName; private final boolean isPrimitiveArray; private final boolean isArray; protected final boolean hasIndex; protected final boolean hasIdentifier; private final boolean isLazy; private final boolean isExtraLazy; private final boolean isInverse; private final boolean isMutable; private final boolean isVersioned; protected final int batchSize; private final FetchMode fetchMode; private final boolean hasOrphanDelete; private final boolean subselectLoadable; //extra information about the element type private final Class elementClass; private final String entityName; private final Dialect dialect; private final SQLExceptionConverter sqlExceptionConverter; private final SessionFactoryImplementor factory; private final EntityPersister ownerPersister; private final IdentifierGenerator identifierGenerator; private final PropertyMapping elementPropertyMapping; private final EntityPersister elementPersister; private final CollectionRegionAccessStrategy cacheAccessStrategy; private final CollectionType collectionType; private CollectionInitializer initializer; private final CacheEntryStructure cacheEntryStructure; // dynamic filters for the collection private final FilterHelper filterHelper; // dynamic filters specifically for many-to-many inside the collection private final FilterHelper manyToManyFilterHelper; private final String manyToManyWhereString; private final String manyToManyWhereTemplate; private final String manyToManyOrderByString; private final String manyToManyOrderByTemplate; // custom sql private final boolean insertCallable; private final boolean updateCallable; private final boolean deleteCallable; private final boolean deleteAllCallable; private ExecuteUpdateResultCheckStyle insertCheckStyle; private ExecuteUpdateResultCheckStyle updateCheckStyle; private ExecuteUpdateResultCheckStyle deleteCheckStyle; private ExecuteUpdateResultCheckStyle deleteAllCheckStyle; private final Serializable[] spaces; private Map collectionPropertyColumnAliases = new HashMap(); private Map collectionPropertyColumnNames = new HashMap(); private static final Logger log = LoggerFactory.getLogger( AbstractCollectionPersister.class ); public AbstractCollectionPersister( final Collection collection, final CollectionRegionAccessStrategy cacheAccessStrategy, final Configuration cfg, final SessionFactoryImplementor factory) throws MappingException, CacheException { this.factory = factory; this.cacheAccessStrategy = cacheAccessStrategy; if ( factory.getSettings().isStructuredCacheEntriesEnabled() ) { cacheEntryStructure = collection.isMap() ? ( CacheEntryStructure ) new StructuredMapCacheEntry() : ( CacheEntryStructure ) new StructuredCollectionCacheEntry(); } else { cacheEntryStructure = new UnstructuredCacheEntry(); } dialect = factory.getDialect(); sqlExceptionConverter = factory.getSQLExceptionConverter(); collectionType = collection.getCollectionType(); role = collection.getRole(); entityName = collection.getOwnerEntityName(); ownerPersister = factory.getEntityPersister(entityName); queryLoaderName = collection.getLoaderName(); nodeName = collection.getNodeName(); isMutable = collection.isMutable(); Table table = collection.getCollectionTable(); fetchMode = collection.getElement().getFetchMode(); elementType = collection.getElement().getType(); //isSet = collection.isSet(); //isSorted = collection.isSorted(); isPrimitiveArray = collection.isPrimitiveArray(); isArray = collection.isArray(); subselectLoadable = collection.isSubselectLoadable(); qualifiedTableName = table.getQualifiedName( dialect, factory.getSettings().getDefaultCatalogName(), factory.getSettings().getDefaultSchemaName() ); int spacesSize = 1 + collection.getSynchronizedTables().size(); spaces = new String[spacesSize]; spaces[0] = qualifiedTableName; Iterator iter = collection.getSynchronizedTables().iterator(); for ( int i = 1; i < spacesSize; i++ ) { spaces[i] = (String) iter.next(); } sqlOrderByString = collection.getOrderBy(); hasOrder = sqlOrderByString != null; sqlOrderByStringTemplate = hasOrder ? Template.renderOrderByStringTemplate(sqlOrderByString, dialect, factory.getSqlFunctionRegistry()) : null; sqlWhereString = StringHelper.isNotEmpty( collection.getWhere() ) ? "( " + collection.getWhere() + ") " : null; hasWhere = sqlWhereString != null; sqlWhereStringTemplate = hasWhere ? Template.renderWhereStringTemplate(sqlWhereString, dialect, factory.getSqlFunctionRegistry()) : null; hasOrphanDelete = collection.hasOrphanDelete(); int batch = collection.getBatchSize(); if ( batch == -1 ) { batch = factory.getSettings().getDefaultBatchFetchSize(); } batchSize = batch; isVersioned = collection.isOptimisticLocked(); // KEY keyType = collection.getKey().getType(); iter = collection.getKey().getColumnIterator(); int keySpan = collection.getKey().getColumnSpan(); keyColumnNames = new String[keySpan]; keyColumnAliases = new String[keySpan]; int k = 0; while ( iter.hasNext() ) { // NativeSQL: collect key column and auto-aliases Column col = ( (Column) iter.next() ); keyColumnNames[k] = col.getQuotedName(dialect); keyColumnAliases[k] = col.getAlias(dialect); k++; } //unquotedKeyColumnNames = StringHelper.unQuote(keyColumnAliases); //ELEMENT String elemNode = collection.getElementNodeName(); if ( elementType.isEntityType() ) { String entityName = ( (EntityType) elementType ).getAssociatedEntityName(); elementPersister = factory.getEntityPersister(entityName); if ( elemNode==null ) { elemNode = cfg.getClassMapping(entityName).getNodeName(); } // NativeSQL: collect element column and auto-aliases } else { elementPersister = null; } elementNodeName = elemNode; int elementSpan = collection.getElement().getColumnSpan(); elementColumnAliases = new String[elementSpan]; elementColumnNames = new String[elementSpan]; elementFormulaTemplates = new String[elementSpan]; elementFormulas = new String[elementSpan]; elementColumnIsSettable = new boolean[elementSpan]; elementColumnIsInPrimaryKey = new boolean[elementSpan]; boolean isPureFormula = true; boolean hasNotNullableColumns = false; int j = 0; iter = collection.getElement().getColumnIterator(); while ( iter.hasNext() ) { Selectable selectable = (Selectable) iter.next(); elementColumnAliases[j] = selectable.getAlias(dialect); if ( selectable.isFormula() ) { Formula form = (Formula) selectable; elementFormulaTemplates[j] = form.getTemplate(dialect, factory.getSqlFunctionRegistry()); elementFormulas[j] = form.getFormula(); } else { Column col = (Column) selectable; elementColumnNames[j] = col.getQuotedName(dialect); elementColumnIsSettable[j] = true; elementColumnIsInPrimaryKey[j] = !col.isNullable(); if ( !col.isNullable() ) { hasNotNullableColumns = true; } isPureFormula = false; } j++; } elementIsPureFormula = isPureFormula; //workaround, for backward compatibility of sets with no //not-null columns, assume all columns are used in the //row locator SQL if ( !hasNotNullableColumns ) { Arrays.fill( elementColumnIsInPrimaryKey, true ); } // INDEX AND ROW SELECT hasIndex = collection.isIndexed(); if (hasIndex) { // NativeSQL: collect index column and auto-aliases IndexedCollection indexedCollection = (IndexedCollection) collection; indexType = indexedCollection.getIndex().getType(); int indexSpan = indexedCollection.getIndex().getColumnSpan(); iter = indexedCollection.getIndex().getColumnIterator(); indexColumnNames = new String[indexSpan]; indexFormulaTemplates = new String[indexSpan]; indexFormulas = new String[indexSpan]; indexColumnIsSettable = new boolean[indexSpan]; indexColumnAliases = new String[indexSpan]; int i = 0; boolean hasFormula = false; while ( iter.hasNext() ) { Selectable s = (Selectable) iter.next(); indexColumnAliases[i] = s.getAlias(dialect); if ( s.isFormula() ) { Formula indexForm = (Formula) s; indexFormulaTemplates[i] = indexForm.getTemplate(dialect, factory.getSqlFunctionRegistry()); indexFormulas[i] = indexForm.getFormula(); hasFormula = true; } else { Column indexCol = (Column) s; indexColumnNames[i] = indexCol.getQuotedName(dialect); indexColumnIsSettable[i] = true; } i++; } indexContainsFormula = hasFormula; baseIndex = indexedCollection.isList() ? ( (List) indexedCollection ).getBaseIndex() : 0; indexNodeName = indexedCollection.getIndexNodeName(); } else { indexContainsFormula = false; indexColumnIsSettable = null; indexFormulaTemplates = null; indexFormulas = null; indexType = null; indexColumnNames = null; indexColumnAliases = null; baseIndex = 0; indexNodeName = null; } hasIdentifier = collection.isIdentified(); if (hasIdentifier) { if ( collection.isOneToMany() ) { throw new MappingException( "one-to-many collections with identifiers are not supported" ); } IdentifierCollection idColl = (IdentifierCollection) collection; identifierType = idColl.getIdentifier().getType(); iter = idColl.getIdentifier().getColumnIterator(); Column col = ( Column ) iter.next(); identifierColumnName = col.getQuotedName(dialect); identifierColumnAlias = col.getAlias(dialect); //unquotedIdentifierColumnName = identifierColumnAlias; identifierGenerator = idColl.getIdentifier().createIdentifierGenerator( factory.getDialect(), factory.getSettings().getDefaultCatalogName(), factory.getSettings().getDefaultSchemaName(), null ); } else { identifierType = null; identifierColumnName = null; identifierColumnAlias = null; //unquotedIdentifierColumnName = null; identifierGenerator = null; } //GENERATE THE SQL: //sqlSelectString = sqlSelectString(); //sqlSelectRowString = sqlSelectRowString(); if ( collection.getCustomSQLInsert() == null ) { sqlInsertRowString = generateInsertRowString(); insertCallable = false; insertCheckStyle = ExecuteUpdateResultCheckStyle.COUNT; } else { sqlInsertRowString = collection.getCustomSQLInsert(); insertCallable = collection.isCustomInsertCallable(); insertCheckStyle = collection.getCustomSQLInsertCheckStyle() == null ? ExecuteUpdateResultCheckStyle.determineDefault( collection.getCustomSQLInsert(), insertCallable ) : collection.getCustomSQLInsertCheckStyle(); } if ( collection.getCustomSQLUpdate() == null ) { sqlUpdateRowString = generateUpdateRowString(); updateCallable = false; updateCheckStyle = ExecuteUpdateResultCheckStyle.COUNT; } else { sqlUpdateRowString = collection.getCustomSQLUpdate(); updateCallable = collection.isCustomUpdateCallable(); updateCheckStyle = collection.getCustomSQLUpdateCheckStyle() == null
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -