📄 abstractcollectionpersister.java
字号:
//$Id: AbstractCollectionPersister.java,v 1.1.2.12 2003/11/24 03:50:45 oneovthafew Exp $
package net.sf.hibernate.collection;
import net.sf.hibernate.metadata.CollectionMetadata;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Iterator;
import net.sf.hibernate.AssertionFailure;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.JDBCException;
import net.sf.hibernate.MappingException;
import net.sf.hibernate.QueryException;
import net.sf.hibernate.cache.CacheConcurrencyStrategy;
import net.sf.hibernate.cache.CacheException;
import net.sf.hibernate.cfg.Configuration;
import net.sf.hibernate.dialect.Dialect;
import net.sf.hibernate.engine.SessionFactoryImplementor;
import net.sf.hibernate.engine.SessionImplementor;
import net.sf.hibernate.id.IdentifierGenerator;
import net.sf.hibernate.impl.MessageHelper;
import net.sf.hibernate.loader.CollectionInitializer;
import net.sf.hibernate.mapping.Collection;
import net.sf.hibernate.mapping.Column;
import net.sf.hibernate.mapping.IdentifierCollection;
import net.sf.hibernate.mapping.IndexedCollection;
import net.sf.hibernate.mapping.Table;
import net.sf.hibernate.persister.ClassPersister;
import net.sf.hibernate.persister.Loadable;
import net.sf.hibernate.persister.PropertyMapping;
import net.sf.hibernate.sql.Alias;
import net.sf.hibernate.sql.SelectFragment;
import net.sf.hibernate.sql.Template;
import net.sf.hibernate.type.AbstractComponentType;
import net.sf.hibernate.type.EntityType;
import net.sf.hibernate.type.PersistentCollectionType;
import net.sf.hibernate.type.Type;
import net.sf.hibernate.util.StringHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Base implementation of the <tt>QueryableCollection</tt> interface.
* @see BasicCollectionPersister
* @see OneToManyPersister
* @author Gavin King
*/
public abstract class AbstractCollectionPersister implements CollectionMetadata, QueryableCollection {
// TODO: encapsulate the protected instance variables!
//private final String sqlSelectString;
private final String sqlDeleteString;
private final String sqlInsertRowString;
private final String sqlUpdateRowString;
private final String sqlDeleteRowString;
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 boolean hasOrphanDelete;
//private final boolean isSet;
private final Type keyType;
private final Type indexType;
protected final Type elementType;
protected final String[] keyColumnNames;
protected final String[] indexColumnNames;
protected final String[] elementColumnNames;
//private final String[] unquotedIndexColumnNames;
//private final String[] unquotedElementColumnNames;
//private final String[] unquotedKeyColumnNames;
protected final String[] rowSelectColumnNames;
protected final String[] indexColumnAliases;
protected final String[] elementColumnAliases;
protected final String[] keyColumnAliases;
private final Type rowSelectType;
private final boolean primitiveArray;
private final boolean array;
//protected final boolean isOneToMany;
protected final String qualifiedTableName;
protected final boolean hasIndex;
private final boolean isLazy;
private final boolean isInverse;
protected final int batchSize;
private final Class elementClass;
private final CacheConcurrencyStrategy cache;
private final PersistentCollectionType collectionType;
private final int enableJoinedFetch;
private final Class ownerClass;
//private final boolean isSorted;
private final IdentifierGenerator identifierGenerator;
private final String unquotedIdentifierColumnName;
private final Type identifierType;
protected final boolean hasIdentifier;
protected final String identifierColumnName;
private final String identifierColumnAlias;
private final Dialect dialect;
private final PropertyMapping elementPropertyMapping;
protected final Loadable elementPersister;
private final CollectionInitializer initializer;
private final String role;
//private final SessionFactoryImplementor factory;
private static final Log log = LogFactory.getLog(BasicCollectionPersister.class);
public AbstractCollectionPersister(Collection collection, Configuration cfg, SessionFactoryImplementor factory)
throws MappingException, CacheException {
dialect = factory.getDialect();
collectionType = collection.getCollectionType();
role = collection.getRole();
ownerClass = collection.getOwnerClass();
Alias alias = new Alias("__");
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();
batchSize = collection.getBatchSize();
cache=collection.getCache();
keyType = collection.getKey().getType();
Iterator iter = collection.getKey().getColumnIterator();
int keySpan = collection.getKey().getColumnSpan();
keyColumnNames = new String[keySpan];
String[] keyAliases = new String[keySpan];
int k=0;
while ( iter.hasNext() ) {
Column col = ( (Column) iter.next() );
keyColumnNames[k] = col.getQuotedName(dialect);
keyAliases[k] = col.getAlias();
k++;
}
keyColumnAliases = alias.toAliasStrings(keyAliases);
//unquotedKeyColumnNames = StringHelper.unQuote(keyColumnAliases);
java.util.Set distinctColumns = new HashSet();
checkColumnDuplication( distinctColumns, collection.getKey().getColumnIterator() );
//isSet = collection.isSet();
//isSorted = collection.isSorted();
primitiveArray = collection.isPrimitiveArray();
array = collection.isArray();
int elementSpan = collection.getElement().getColumnSpan();
iter = collection.getElement().getColumnIterator();
Table table = collection.getCollectionTable();
enableJoinedFetch = collection.getElement().getOuterJoinFetchSetting();
elementType = collection.getElement().getType();
if ( !collection.isOneToMany() ) checkColumnDuplication( distinctColumns, collection.getElement().getColumnIterator() );
if ( elementType.isEntityType() ) {
//TODO: what if it is just an ordinary ClassPersister, not Loadable
// can the collection fwk even handle that?
elementPersister = (Loadable) factory.getPersister( ( (EntityType) elementType ).getAssociatedClass() );
}
else {
elementPersister = null;
}
qualifiedTableName = table.getQualifiedName( dialect, factory.getDefaultSchema() );
String[] aliases = new String[elementSpan];
elementColumnNames = new String[elementSpan];
int j=0;
while ( iter.hasNext() ) {
Column col = (Column) iter.next();
elementColumnNames[j] = col.getQuotedName(dialect);
aliases[j] = col.getAlias();
j++;
}
elementColumnAliases = alias.toAliasStrings(aliases);
//unquotedElementColumnNames = StringHelper.unQuote(elementColumnAliases);
Type selectColumns;
String[] selectType;
if ( hasIndex = collection.isIndexed() ) {
IndexedCollection indexedCollection = (IndexedCollection) collection;
indexType = indexedCollection.getIndex().getType();
int indexSpan = indexedCollection.getIndex().getColumnSpan();
iter = indexedCollection.getIndex().getColumnIterator();
indexColumnNames = new String[indexSpan];
String[] indexAliases = new String[indexSpan];
int i=0;
while ( iter.hasNext() ) {
Column indexCol = (Column) iter.next();
indexAliases[i] = indexCol.getAlias();
indexColumnNames[i] = indexCol.getQuotedName(dialect);
i++;
}
selectType = indexColumnNames;
selectColumns = indexType;
indexColumnAliases = alias.toAliasStrings(indexAliases);
//unquotedIndexColumnNames = StringHelper.unQuote(indexColumnAliases);
checkColumnDuplication( distinctColumns, indexedCollection.getIndex().getColumnIterator() );
}
else {
indexType = null;
indexColumnNames = null;
indexColumnAliases = null;
selectType = elementColumnNames;
selectColumns = elementType;
}
if ( hasIdentifier = collection.isIdentified() ) {
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);
selectType = new String[] { identifierColumnName };
selectColumns = identifierType;
identifierColumnAlias = alias.toAliasString( col.getAlias() );
//unquotedIdentifierColumnName = StringHelper.unQuote(identifierColumnAlias);
unquotedIdentifierColumnName = identifierColumnAlias;
identifierGenerator = idColl.getIdentifier().createIdentifierGenerator( factory.getDialect() );
checkColumnDuplication( distinctColumns, idColl.getIdentifier().getColumnIterator() );
}
else {
identifierType = null;
identifierColumnName = null;
identifierColumnAlias = null;
unquotedIdentifierColumnName = null;
identifierGenerator = null;
}
rowSelectColumnNames = selectType;
rowSelectType = selectColumns;
//sqlSelectString = sqlSelectString();
sqlDeleteString = generateDeleteString();
//sqlSelectRowString = sqlSelectRowString();
sqlInsertRowString = generateInsertRowString();
sqlUpdateRowString = generateUpdateRowString();
sqlDeleteRowString = generateDeleteRowString();
isLazy = collection.isLazy();
isInverse = collection.isInverse();
if ( collection.isArray() ) {
elementClass = ( (net.sf.hibernate.mapping.Array) collection ).getElementClass();
}
else {
// for non-arrays, we don't need to know the element class
elementClass = null; //elementType.returnedClass();
}
initializer = createCollectionInitializer(factory);
if ( elementType.isComponentType() ) {
elementPropertyMapping = new CompositeElementPropertyMapping(
elementColumnNames, (AbstractComponentType) elementType, factory
);
}
else if ( !elementType.isEntityType() ) {
elementPropertyMapping = new ElementPropertyMapping(elementColumnNames, elementType);
}
else {
ClassPersister persister = factory.getPersister( ( (EntityType) elementType ).getAssociatedClass() );
if ( persister instanceof PropertyMapping ) { //not all classpersisters implement PropertyMapping!
elementPropertyMapping = (PropertyMapping) persister;
}
else {
elementPropertyMapping = new ElementPropertyMapping(elementColumnNames, elementType);
}
}
}
public void initialize(Serializable key, SessionImplementor session) throws HibernateException {
try {
initializer.initialize(key, session);
}
catch (SQLException sqle) {
throw new JDBCException(
"could not initialize collection: " + MessageHelper.infoString(this, key), sqle
);
}
}
protected abstract CollectionInitializer createCollectionInitializer(SessionFactoryImplementor factory) throws MappingException;
public CacheConcurrencyStrategy getCache() {
return cache;
}
public boolean hasCache() {
return cache!=null;
}
public PersistentCollectionType getCollectionType() {
return collectionType;
}
public String getSQLWhereString(String alias) {
return StringHelper.replace(sqlWhereStringTemplate, Template.TEMPLATE, alias);
}
public String getSQLOrderByString(String alias) {
return StringHelper.replace(sqlOrderByStringTemplate, Template.TEMPLATE, alias);
}
public int enableJoinedFetch() {
return enableJoinedFetch;
}
public boolean hasOrdering() {
return hasOrder;
}
public boolean hasWhere() {
return hasWhere;
}
protected String getSQLDeleteString() {
return sqlDeleteString;
}
protected String getSQLInsertRowString() {
return sqlInsertRowString;
}
protected String getSQLUpdateRowString() {
return sqlUpdateRowString;
}
protected String getSQLDeleteRowString() {
return sqlDeleteRowString;
}
public Type getKeyType() {
return keyType;
}
public Type getIndexType() {
return indexType;
}
public Type getElementType() {
return elementType;
}
/**
* Return the element class of an array, or null otherwise
*/
public Class getElementClass() { //needed by arrays
return elementClass;
}
public Object readElement(ResultSet rs, Object owner, SessionImplementor session) throws HibernateException, SQLException {
Object element = getElementType().nullSafeGet(rs, elementColumnAliases, session, owner);
return element;
}
public Object readIndex(ResultSet rs, SessionImplementor session) throws HibernateException, SQLException {
Object index = getIndexType().nullSafeGet(rs, indexColumnAliases, session, null);
if (index==null) throw new HibernateException("null index column for collection: " + role);
return index;
}
public Object readIdentifier(ResultSet rs, SessionImplementor session) throws HibernateException, SQLException {
Object id = getIdentifierType().nullSafeGet(rs, unquotedIdentifierColumnName, session, null);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -