📄 statefulpersistencecontext.java
字号:
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. * * @param coll The collection for which we are adding an entry. * @param entry The entry representing the collection. * @param key The key of the collection's 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 * * @param collection The collection for which we are adding an entry. * @param persister The collection persister */ private void addCollection(PersistentCollection collection, CollectionPersister persister) { 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. * <p/> * Additionally, ensure that any load optimization references * such as batch or subselect loading get cleaned up as well. * * @param key The key of the entity proxy to be removed * @return The proxy reference. */ public Object removeProxy(EntityKey key) { if ( batchFetchQueue != null ) { batchFetchQueue.removeBatchLoadableEntityKey( key ); batchFetchQueue.removeSubselect( 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); }*/ /** * Retrieve the set of EntityKeys representing nullifiable references */ public HashSet getNullifiableEntityKeys() { return nullifiableEntityKeys; } public Map getEntitiesByKey() { return entitiesByKey; } public Map getEntityEntries() { return entityEntries; } public Map getCollectionEntries() { return collectionEntries; } public Map getCollectionsByKey() { return collectionsByKey; } /** * Do we already know that the entity does not exist in the * database? */ /*public boolean isNonExistant(EntityKey key) { return nonExistantEntityKeys.contains(key); }*/ /** * Do we already know that the entity does not exist in the * database? */ /*public boolean isNonExistant(EntityUniqueKey key) { return nonExistentEntityUniqueKeys.contains(key); }*/ public int getCascadeLevel() { return cascading; } public int incrementCascadeLevel() { return ++cascading; } public int decrementCascadeLevel() { return --cascading; } public boolean isFlushing() { return flushing; } public void setFlushing(boolean flushing) { this.flushing = flushing; } /** * Call this before begining a two-phase load */ public void beforeLoad() { loadCounter++; } /** * Call this after finishing a two-phase load */ public void afterLoad() { loadCounter--; } /** * Returns a string representation of the object. * * @return a string representation of the object. */ public String toString() { return new StringBuffer() .append("PersistenceContext[entityKeys=") .append(entitiesByKey.keySet()) .append(",collectionKeys=") .append(collectionsByKey.keySet()) .append("]") .toString(); } /** * Search <tt>this</tt> persistence context for an associated entity instance which is considered the "owner" of * the given <tt>childEntity</tt>, and return that owner's id value. This is performed in the scenario of a * uni-directional, non-inverse one-to-many collection (which means that the collection elements do not maintain * a direct reference to the owner). * <p/> * As such, the processing here is basically to loop over every entity currently associated with this persistence * context and for those of the correct entity (sub) type to extract its collection role property value and see * if the child is contained within that collection. If so, we have found the owner; if not, we go on. * <p/> * Also need to account for <tt>mergeMap</tt> which acts as a local copy cache managed for the duration of a merge * operation. It represents a map of the detached entity instances pointing to the corresponding managed instance. * * @param entityName The entity name for the entity type which would own the child * @param propertyName The name of the property on the owning entity type which would name this child association. * @param childEntity The child entity instance for which to locate the owner instance id. * @param mergeMap A map of non-persistent instances from an on-going merge operation (possibly null). * * @return The id of the entityName instance which is said to own the child; null if an appropriate owner not * located. */ public Serializable getOwnerId(String entityName, String propertyName, Object childEntity, Map mergeMap) { final String collectionRole = entityName + '.' + propertyName; final EntityPersister persister = session.getFactory().getEntityPersister( entityName ); final CollectionPersister collectionPersister = session.getFactory().getCollectionPersister( collectionRole ); // iterate all the entities currently associated with the persistence context. Iterator entities = entityEntries.entrySet().iterator(); while ( entities.hasNext() ) { final Map.Entry me = ( Map.Entry ) entities.next(); final EntityEntry entityEntry = ( EntityEntry ) me.getValue(); // does this entity entry pertain to the entity persister in which we are interested (owner)? if ( persister.isSubclassEntityName( entityEntry.getEntityName() ) ) { final Object entityEntryInstance = me.getKey(); //check if the managed object is the parent boolean found = isFoundInParent( propertyName, childEntity, persister, collectionPersister, entityEntryInstance ); if ( !found && mergeMap != null ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -