📄 statefulpersistencecontext.java
字号:
public boolean containsCollection(PersistentCollection collection) {
return collectionEntries.containsKey(collection);
}
public boolean containsProxy(Object entity) {
return proxiesByKey.containsValue( entity );
}
/**
* Takes the given object and, if it represents a proxy, reassociates it with this event source.
*
* @param value The possible proxy to be reassociated.
* @return Whether the passed value represented an actual proxy which got initialized.
* @throws MappingException
*/
public boolean reassociateIfUninitializedProxy(Object value) throws MappingException {
if ( value instanceof ElementWrapper ) {
value = ( (ElementWrapper) value ).getElement();
}
if ( !Hibernate.isInitialized(value) ) {
HibernateProxy proxy = (HibernateProxy) value;
LazyInitializer li = proxy.getHibernateLazyInitializer();
reassociateProxy(li, proxy);
return true;
}
else {
return false;
}
}
/**
* If a deleted entity instance is re-saved, and it has a proxy, we need to
* reset the identifier of the proxy
*/
public void reassociateProxy(Object value, Serializable id) throws MappingException {
if ( value instanceof ElementWrapper ) {
value = ( (ElementWrapper) value ).getElement();
}
if ( value instanceof HibernateProxy ) {
if ( log.isDebugEnabled() ) log.debug("setting proxy identifier: " + id);
HibernateProxy proxy = (HibernateProxy) value;
LazyInitializer li = proxy.getHibernateLazyInitializer();
li.setIdentifier(id);
reassociateProxy(li, proxy);
}
}
/**
* Associate a proxy that was instantiated by another session with this session
*/
private void reassociateProxy(LazyInitializer li, HibernateProxy proxy) throws HibernateException {
if ( li.getSession() != this ) {
EntityPersister persister = session.getFactory().getEntityPersister( li.getEntityName() );
EntityKey key = new EntityKey( li.getIdentifier(), persister, session.getEntityMode() );
if ( !proxiesByKey.containsKey(key) ) proxiesByKey.put(key, proxy); // any earlier proxy takes precedence
proxy.getHibernateLazyInitializer().setSession(session);
}
}
/**
* Get the entity instance underlying the given proxy, throwing
* an exception if the proxy is uninitialized. If the given object
* is not a proxy, simply return the argument.
*/
public Object unproxy(Object maybeProxy) throws HibernateException {
if ( maybeProxy instanceof ElementWrapper ) {
maybeProxy = ( (ElementWrapper) maybeProxy ).getElement();
}
if ( maybeProxy instanceof HibernateProxy ) {
HibernateProxy proxy = (HibernateProxy) maybeProxy;
LazyInitializer li = proxy.getHibernateLazyInitializer();
if ( li.isUninitialized() ) {
throw new PersistentObjectException(
"object was an uninitialized proxy for " +
li.getEntityName()
);
}
return li.getImplementation(); //unwrap the object
}
else {
return maybeProxy;
}
}
/**
* Possibly unproxy the given reference and reassociate it with the current session.
*
* @param maybeProxy The reference to be unproxied if it currently represents a proxy.
* @return The unproxied instance.
* @throws HibernateException
*/
public Object unproxyAndReassociate(Object maybeProxy) throws HibernateException {
if ( maybeProxy instanceof ElementWrapper ) {
maybeProxy = ( (ElementWrapper) maybeProxy ).getElement();
}
if ( maybeProxy instanceof HibernateProxy ) {
HibernateProxy proxy = (HibernateProxy) maybeProxy;
LazyInitializer li = proxy.getHibernateLazyInitializer();
reassociateProxy(li, proxy);
return li.getImplementation(); //initialize + unwrap the object
}
else {
return maybeProxy;
}
}
/**
* Attempts to check whether the given key represents an entity already loaded within the
* current session.
* @param object The entity reference against which to perform the uniqueness check.
* @throws HibernateException
*/
public void checkUniqueness(EntityKey key, Object object) throws HibernateException {
Object entity = getEntity(key);
if ( entity == object ) {
throw new AssertionFailure( "object already associated, but no entry was found" );
}
if ( entity != null ) {
throw new NonUniqueObjectException( key.getIdentifier(), key.getEntityName() );
}
}
/**
* If the existing proxy is insufficiently "narrow" (derived), instantiate a new proxy
* and overwrite the registration of the old one. This breaks == and occurs only for
* "class" proxies rather than "interface" proxies. Also init the proxy to point to
* the given target implementation if necessary.
*
* @param proxy The proxy instance to be narrowed.
* @param persister The persister for the proxied entity.
* @param key The internal cache key for the proxied entity.
* @param object (optional) the actual proxied entity instance.
* @return An appropriately narrowed instance.
* @throws HibernateException
*/
public Object narrowProxy(Object proxy, EntityPersister persister, EntityKey key, Object object)
throws HibernateException {
boolean alreadyNarrow = persister.getConcreteProxyClass( session.getEntityMode() )
.isAssignableFrom( proxy.getClass() );
if ( !alreadyNarrow ) {
if ( PROXY_WARN_LOG.isWarnEnabled() ) {
PROXY_WARN_LOG.warn(
"Narrowing proxy to " +
persister.getConcreteProxyClass( session.getEntityMode() ) +
" - this operation breaks =="
);
}
if ( object != null ) {
proxiesByKey.remove(key);
return object; //return the proxied object
}
else {
proxy = persister.createProxy( key.getIdentifier(), session );
proxiesByKey.put(key, proxy); //overwrite old proxy
return proxy;
}
}
else {
if ( object != null ) {
LazyInitializer li = ( (HibernateProxy) proxy ).getHibernateLazyInitializer();
li.setImplementation(object);
}
return proxy;
}
}
/**
* Return the existing proxy associated with the given <tt>EntityKey</tt>, or the
* third argument (the entity associated with the key) if no proxy exists. Init
* the proxy to the target implementation, if necessary.
*/
public Object proxyFor(EntityPersister persister, EntityKey key, Object impl)
throws HibernateException {
if ( !persister.hasProxy() ) return impl;
Object proxy = proxiesByKey.get(key);
if ( proxy != null ) {
return narrowProxy(proxy, persister, key, impl);
}
else {
return impl;
}
}
/**
* Return the existing proxy associated with the given <tt>EntityKey</tt>, or the
* argument (the entity associated with the key) if no proxy exists.
* (slower than the form above)
*/
public Object proxyFor(Object impl) throws HibernateException {
EntityEntry e = getEntry(impl);
EntityPersister p = e.getPersister();
return proxyFor( p, new EntityKey( e.getId(), p, session.getEntityMode() ), impl );
}
/**
* Get the entity that owns this persistent collection
*/
public Object getCollectionOwner(Serializable key, CollectionPersister collectionPersister) throws MappingException {
return getEntity( new EntityKey( key, collectionPersister.getOwnerEntityPersister(), session.getEntityMode() ) );
}
/**
* add a collection we just loaded up (still needs initializing)
*/
public void addUninitializedCollection(CollectionPersister persister, PersistentCollection collection, Serializable id) {
CollectionEntry ce = new CollectionEntry(collection, persister, id, flushing);
addCollection(collection, ce, id);
}
/**
* add a detached uninitialized collection
*/
public void addUninitializedDetachedCollection(CollectionPersister persister, PersistentCollection collection) {
CollectionEntry ce = new CollectionEntry( persister, collection.getKey() );
addCollection( collection, ce, collection.getKey() );
}
/**
* Add a new collection (ie. a newly created one, just instantiated by the
* application, with no database state or snapshot)
* @param collection The collection to be associated with the persistence context
*/
public void addNewCollection(CollectionPersister persister, PersistentCollection collection)
throws HibernateException {
addCollection(collection, persister);
}
/**
* Add an collection to the cache, with a given collection entry
*/
private void addCollection(PersistentCollection coll, CollectionEntry entry, Serializable key) {
collectionEntries.put(coll, entry);
CollectionKey collectionKey = new CollectionKey( entry.getLoadedPersister(), key, session.getEntityMode() );
PersistentCollection old = (PersistentCollection) collectionsByKey.put(collectionKey, coll);
if ( old != null ) {
if (old==coll) throw new AssertionFailure("bug adding collection twice");
// or should it actually throw an exception?
old.unsetSession(session);
collectionEntries.remove(old);
// watch out for a case where old is still referenced
// somewhere in the object graph! (which is a user error)
}
}
/**
* Add a collection to the cache, creating a new collection entry for it
*/
private void addCollection(PersistentCollection collection, CollectionPersister persister)
throws HibernateException {
CollectionEntry ce = new CollectionEntry(persister, collection);
collectionEntries.put(collection, ce);
}
/**
* add an (initialized) collection that was created by another session and passed
* into update() (ie. one with a snapshot and existing state on the database)
*/
public void addInitializedDetachedCollection(CollectionPersister collectionPersister, PersistentCollection collection)
throws HibernateException {
if ( collection.isUnreferenced() ) {
//treat it just like a new collection
addCollection( collection, collectionPersister );
}
else {
CollectionEntry ce = new CollectionEntry( collection, session.getFactory() );
addCollection( collection, ce, collection.getKey() );
}
}
/**
* add a collection we just pulled out of the cache (does not need initializing)
*/
public CollectionEntry addInitializedCollection(CollectionPersister persister, PersistentCollection collection, Serializable id)
throws HibernateException {
CollectionEntry ce = new CollectionEntry(collection, persister, id, flushing);
ce.postInitialize(collection);
addCollection(collection, ce, id);
return ce;
}
/**
* Get the collection instance associated with the <tt>CollectionKey</tt>
*/
public PersistentCollection getCollection(CollectionKey collectionKey) {
return (PersistentCollection) collectionsByKey.get(collectionKey);
}
/**
* Register a collection for non-lazy loading at the end of the
* two-phase load
*/
public void addNonLazyCollection(PersistentCollection collection) {
nonlazyCollections.add(collection);
}
/**
* Force initialization of all non-lazy collections encountered during
* the current two-phase load (actually, this is a no-op, unless this
* is the "outermost" load)
*/
public void initializeNonLazyCollections() throws HibernateException {
if ( loadCounter == 0 ) {
log.debug( "initializing non-lazy collections" );
//do this work only at the very highest level of the load
loadCounter++; //don't let this method be called recursively
try {
int size;
while ( ( size = nonlazyCollections.size() ) > 0 ) {
//note that each iteration of the loop may add new elements
( (PersistentCollection) nonlazyCollections.remove( size - 1 ) ).forceInitialization();
}
}
finally {
loadCounter--;
clearNullProperties();
}
}
}
/**
* Get the <tt>PersistentCollection</tt> object for an array
*/
public PersistentCollection getCollectionHolder(Object array) {
return (PersistentCollection) arrayHolders.get(array);
}
/**
* Register a <tt>PersistentCollection</tt> object for an array.
* Associates a holder with an array - MUST be called after loading
* array, since the array instance is not created until endLoad().
*/
public void addCollectionHolder(PersistentCollection holder) {
//TODO:refactor + make this method private
arrayHolders.put( holder.getValue(), holder );
}
public PersistentCollection removeCollectionHolder(Object array) {
return (PersistentCollection) arrayHolders.remove(array);
}
/**
* Get the snapshot of the pre-flush collection state
*/
public Serializable getSnapshot(PersistentCollection coll) {
return getCollectionEntry(coll).getSnapshot();
}
/**
* Get the collection entry for a collection passed to filter,
* which might be a collection wrapper, an array, or an unwrapped
* collection. Return null if there is no entry.
*/
public CollectionEntry getCollectionEntryOrNull(Object collection) {
PersistentCollection coll;
if ( collection instanceof PersistentCollection ) {
coll = (PersistentCollection) collection;
//if (collection==null) throw new TransientObjectException("Collection was not yet persistent");
}
else {
coll = getCollectionHolder(collection);
if ( coll == null ) {
//it might be an unwrapped collection reference!
//try to find a wrapper (slowish)
Iterator wrappers = IdentityMap.keyIterator(collectionEntries);
while ( wrappers.hasNext() ) {
PersistentCollection pc = (PersistentCollection) wrappers.next();
if ( pc.isWrapper(collection) ) {
coll = pc;
break;
}
}
}
}
return (coll == null) ? null : getCollectionEntry(coll);
}
/**
* Get an existing proxy by key
*/
public Object getProxy(EntityKey key) {
return proxiesByKey.get(key);
}
/**
* Add a proxy to the session cache
*/
public void addProxy(EntityKey key, Object proxy) {
proxiesByKey.put(key, proxy);
}
/**
* Remove a proxy from the session cache
*/
public Object removeProxy(EntityKey key) {
return proxiesByKey.remove(key);
}
/**
* Record the fact that an entity does not exist in the database
*
* @param key the primary key of the entity
*/
/*public void addNonExistantEntityKey(EntityKey key) {
nonExistantEntityKeys.add(key);
}*/
/**
* Record the fact that an entity does not exist in the database
*
* @param key a unique key of the entity
*/
/*public void addNonExistantEntityUniqueKey(EntityUniqueKey key) {
nonExistentEntityUniqueKeys.add(key);
}*/
/*public void removeNonExist(EntityKey key) {
nonExistantEntityKeys.remove(key);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -