⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 collectiontype.java

📁 一个Java持久层类库
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
// $Id: CollectionType.java 11302 2007-03-19 20:44:11Z steve.ebersole@jboss.com $package org.hibernate.type;import java.io.Serializable;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;import java.util.List;import java.util.Map;import org.dom4j.Element;import org.dom4j.Node;import org.hibernate.EntityMode;import org.hibernate.Hibernate;import org.hibernate.HibernateException;import org.hibernate.MappingException;import org.hibernate.collection.PersistentCollection;import org.hibernate.engine.CollectionKey;import org.hibernate.engine.EntityEntry;import org.hibernate.engine.Mapping;import org.hibernate.engine.PersistenceContext;import org.hibernate.engine.SessionFactoryImplementor;import org.hibernate.engine.SessionImplementor;import org.hibernate.persister.collection.CollectionPersister;import org.hibernate.persister.collection.QueryableCollection;import org.hibernate.persister.entity.EntityPersister;import org.hibernate.persister.entity.Joinable;import org.hibernate.proxy.HibernateProxy;import org.hibernate.proxy.LazyInitializer;import org.hibernate.util.ArrayHelper;import org.hibernate.util.MarkerObject;/** * A type that handles Hibernate <tt>PersistentCollection</tt>s (including arrays). *  * @author Gavin King */public abstract class CollectionType extends AbstractType implements AssociationType {	private static final Object NOT_NULL_COLLECTION = new MarkerObject( "NOT NULL COLLECTION" );	public static final Object UNFETCHED_COLLECTION = new MarkerObject( "UNFETCHED COLLECTION" );	private final String role;	private final String foreignKeyPropertyName;	private final boolean isEmbeddedInXML;	public CollectionType(String role, String foreignKeyPropertyName, boolean isEmbeddedInXML) {		this.role = role;		this.foreignKeyPropertyName = foreignKeyPropertyName;		this.isEmbeddedInXML = isEmbeddedInXML;	}		public boolean isEmbeddedInXML() {		return isEmbeddedInXML;	}	public String getRole() {		return role;	}	public Object indexOf(Object collection, Object element) {		throw new UnsupportedOperationException( "generic collections don't have indexes" );	}	public boolean contains(Object collection, Object childObject, SessionImplementor session) {		// we do not have to worry about queued additions to uninitialized		// collections, since they can only occur for inverse collections!		Iterator elems = getElementsIterator( collection, session );		while ( elems.hasNext() ) {			Object element = elems.next();			// worrying about proxies is perhaps a little bit of overkill here...			if ( element instanceof HibernateProxy ) {				LazyInitializer li = ( (HibernateProxy) element ).getHibernateLazyInitializer();				if ( !li.isUninitialized() ) element = li.getImplementation();			}			if ( element == childObject ) return true;		}		return false;	}	public boolean isCollectionType() {		return true;	}	public final boolean isEqual(Object x, Object y, EntityMode entityMode) {		return x == y			|| ( x instanceof PersistentCollection && ( (PersistentCollection) x ).isWrapper( y ) )			|| ( y instanceof PersistentCollection && ( (PersistentCollection) y ).isWrapper( x ) );	}	public int compare(Object x, Object y, EntityMode entityMode) {		return 0; // collections cannot be compared	}	public int getHashCode(Object x, EntityMode entityMode) {		throw new UnsupportedOperationException( "cannot perform lookups on collections" );	}	/**	 * Instantiate an uninitialized collection wrapper or holder. Callers MUST add the holder to the	 * persistence context!	 *	 * @param session The session from which the request is originating.	 * @param persister The underlying collection persister (metadata)	 * @param key The owner key.	 * @return The instantiated collection.	 */	public abstract PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key);	public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner) throws SQLException {		return nullSafeGet( rs, new String[] { name }, session, owner );	}	public Object nullSafeGet(ResultSet rs, String[] name, SessionImplementor session, Object owner)			throws HibernateException, SQLException {		return resolve( null, session, owner );	}	public final void nullSafeSet(PreparedStatement st, Object value, int index, boolean[] settable,			SessionImplementor session) throws HibernateException, SQLException {		//NOOP	}	public void nullSafeSet(PreparedStatement st, Object value, int index,			SessionImplementor session) throws HibernateException, SQLException {	}	public int[] sqlTypes(Mapping session) throws MappingException {		return ArrayHelper.EMPTY_INT_ARRAY;	}	public int getColumnSpan(Mapping session) throws MappingException {		return 0;	}	public String toLoggableString(Object value, SessionFactoryImplementor factory)			throws HibernateException {		if ( value == null ) {			return "null";		}		else if ( !Hibernate.isInitialized( value ) ) {			return "<uninitialized>";		}		else {			return renderLoggableString( value, factory );		}	}	protected String renderLoggableString(Object value, SessionFactoryImplementor factory)			throws HibernateException {		if ( Element.class.isInstance( value ) ) {			// for DOM4J "collections" only			// TODO: it would be better if this was done at the higher level by Printer			return ( ( Element ) value ).asXML();		}		else {			List list = new ArrayList();			Type elemType = getElementType( factory );			Iterator iter = getElementsIterator( value );			while ( iter.hasNext() ) {				list.add( elemType.toLoggableString( iter.next(), factory ) );			}			return list.toString();		}	}	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory)			throws HibernateException {		return value;	}	public String getName() {		return getReturnedClass().getName() + '(' + getRole() + ')';	}	/**	 * Get an iterator over the element set of the collection, which may not yet be wrapped	 *	 * @param collection The collection to be iterated	 * @param session The session from which the request is originating.	 * @return The iterator.	 */	public Iterator getElementsIterator(Object collection, SessionImplementor session) {		if ( session.getEntityMode()==EntityMode.DOM4J ) {			final SessionFactoryImplementor factory = session.getFactory();			final CollectionPersister persister = factory.getCollectionPersister( getRole() );			final Type elementType = persister.getElementType();						List elements = ( (Element) collection ).elements( persister.getElementNodeName() );			ArrayList results = new ArrayList();			for ( int i=0; i<elements.size(); i++ ) {				Element value = (Element) elements.get(i);				results.add( elementType.fromXMLNode( value, factory ) );			}			return results.iterator();		}		else {			return getElementsIterator(collection);		}	}	/**	 * Get an iterator over the element set of the collection in POJO mode	 *	 * @param collection The collection to be iterated	 * @return The iterator.	 */	protected Iterator getElementsIterator(Object collection) {		return ( (Collection) collection ).iterator();	}	public boolean isMutable() {		return false;	}	public Serializable disassemble(Object value, SessionImplementor session, Object owner)			throws HibernateException {		//remember the uk value				//This solution would allow us to eliminate the owner arg to disassemble(), but		//what if the collection was null, and then later had elements added? seems unsafe		//session.getPersistenceContext().getCollectionEntry( (PersistentCollection) value ).getKey();				final Serializable key = getKeyOfOwner(owner, session);		if (key==null) {			return null;		}		else {			return getPersister(session)					.getKeyType()					.disassemble( key, session, owner );		}	}	public Object assemble(Serializable cached, SessionImplementor session, Object owner)			throws HibernateException {		//we must use the "remembered" uk value, since it is 		//not available from the EntityEntry during assembly		if (cached==null) {			return null;		}		else {			final Serializable key = (Serializable) getPersister(session)					.getKeyType()					.assemble( cached, session, owner);			return resolveKey( key, session, owner );		}	}	/**	 * Is the owning entity versioned?	 *	 * @param session The session from which the request is originating.	 * @return True if the collection owner is versioned; false otherwise.	 * @throws org.hibernate.MappingException Indicates our persister could not be located.	 */	private boolean isOwnerVersioned(SessionImplementor session) throws MappingException {		return getPersister( session ).getOwnerEntityPersister().isVersioned();	}	/**	 * Get our underlying collection persister (using the session to access the	 * factory).	 *	 * @param session The session from which the request is originating.	 * @return The underlying collection persister	 */	private CollectionPersister getPersister(SessionImplementor session) {		return session.getFactory().getCollectionPersister( role );	}	public boolean isDirty(Object old, Object current, SessionImplementor session)			throws HibernateException {		// collections don't dirty an unversioned parent entity		// TODO: I don't really like this implementation; it would be better if		// this was handled by searchForDirtyCollections()		return isOwnerVersioned( session ) && super.isDirty( old, current, session );		// return false;	}	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session)			throws HibernateException {		return isDirty(old, current, session);	}	/**	 * Wrap the naked collection instance in a wrapper, or instantiate a	 * holder. Callers <b>MUST</b> add the holder to the persistence context!	 *	 * @param session The session from which the request is originating.	 * @param collection The bare collection to be wrapped.	 * @return The wrapped collection.	 */	public abstract PersistentCollection wrap(SessionImplementor session, Object collection);	/**	 * Note: return true because this type is castable to <tt>AssociationType</tt>. Not because	 * all collections are associations.	 */	public boolean isAssociationType() {		return true;	}	public ForeignKeyDirection getForeignKeyDirection() {		return ForeignKeyDirection.FOREIGN_KEY_TO_PARENT;	}	/**	 * Get the key value from the owning entity instance, usually the identifier, but might be some	 * other unique key, in the case of property-ref	 *	 * @param owner The collection owner	 * @param session The session from which the request is originating.	 * @return The collection owner's key	 */	public Serializable getKeyOfOwner(Object owner, SessionImplementor session) {				EntityEntry entityEntry = session.getPersistenceContext().getEntry( owner );		if ( entityEntry == null ) return null; // This just handles a particular case of component									  // projection, perhaps get rid of it and throw an exception				if ( foreignKeyPropertyName == null ) {			return entityEntry.getId();		}		else {			// TODO: at the point where we are resolving collection references, we don't			// know if the uk value has been resolved (depends if it was earlier or			// later in the mapping document) - now, we could try and use e.getStatus()			// to decide to semiResolve(), trouble is that initializeEntity() reuses			// the same array for resolved and hydrated values			Object id;			if ( entityEntry.getLoadedState() != null ) {				id = entityEntry.getLoadedValue( foreignKeyPropertyName );			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -