📄 abstractcollectionpersister.java
字号:
//$Id: AbstractCollectionPersister.java 8410 2005-10-14 22:43:44Z maxcsaucdk $
package org.hibernate.persister.collection;
import java.io.Serializable;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.AssertionFailure;
import org.hibernate.FetchMode;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.QueryException;
import org.hibernate.cache.CacheConcurrencyStrategy;
import org.hibernate.cache.CacheException;
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.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 CacheConcurrencyStrategy cache;
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;
// custom sql
private final boolean insertCallable;
private final boolean updateCallable;
private final boolean deleteCallable;
private final boolean deleteAllCallable;
private final Serializable[] spaces;
private Map collectionPropertyColumnAliases = new HashMap();
private Map collectionPropertyColumnNames = new HashMap();
private static final Log log = LogFactory.getLog( AbstractCollectionPersister.class );
public AbstractCollectionPersister(
final Collection collection,
final CacheConcurrencyStrategy cache,
final Configuration cfg,
final SessionFactoryImplementor factory)
throws MappingException, CacheException {
this.factory = factory;
this.cache = cache;
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) :
null;
sqlWhereString = collection.getWhere();
hasWhere = sqlWhereString != null;
sqlWhereStringTemplate = hasWhere ?
Template.renderWhereStringTemplate(sqlWhereString, dialect) :
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);
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);
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -