org.hibernate.engine.spi.CollectionKey Java Examples

The following examples show how to use org.hibernate.engine.spi.CollectionKey. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: EvictVisitor.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
private void evictCollection(PersistentCollection collection) {
	CollectionEntry ce = (CollectionEntry) getSession().getPersistenceContext().getCollectionEntries().remove(collection);
	if ( LOG.isDebugEnabled() ) {
		LOG.debugf(
				"Evicting collection: %s",
				MessageHelper.collectionInfoString( ce.getLoadedPersister(),
						collection,
						ce.getLoadedKey(),
						getSession() ) );
	}
	if (ce.getLoadedPersister() != null && ce.getLoadedPersister().getBatchSize() > 1) {
		getSession().getPersistenceContext().getBatchFetchQueue().removeBatchLoadableCollection(ce);
	}
	if ( ce.getLoadedPersister() != null && ce.getLoadedKey() != null ) {
		//TODO: is this 100% correct?
		getSession().getPersistenceContext().getCollectionsByKey().remove(
				new CollectionKey( ce.getLoadedPersister(), ce.getLoadedKey() )
		);
	}
}
 
Example #2
Source File: StatefulPersistenceContext.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Add a 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 );
	final CollectionKey collectionKey = new CollectionKey( entry.getLoadedPersister(), key );
	final PersistentCollection old = 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)
	}
}
 
Example #3
Source File: AbstractReactiveFlushingEventListener.java    From hibernate-reactive with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * 1. Recreate the collection key to collection map
 * 2. rebuild the collection entries
 * 3. call Interceptor.postFlush()
 */
protected void postFlush(SessionImplementor session) throws HibernateException {

	LOG.trace( "Post flush" );

	final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
	persistenceContext.clearCollectionsByKey();

	// the database has changed now, so the subselect results need to be invalidated
	// the batch fetching queues should also be cleared - especially the collection batch fetching one
	persistenceContext.getBatchFetchQueue().clear();

	persistenceContext.forEachCollectionEntry(
			(persistentCollection, collectionEntry) -> {
				collectionEntry.postFlush( persistentCollection );
				if ( collectionEntry.getLoadedPersister() == null ) {
					//if the collection is dereferenced, unset its session reference and remove from the session cache
					//iter.remove(); //does not work, since the entrySet is not backed by the set
					persistentCollection.unsetSession( session );
					persistenceContext.removeCollectionEntry( persistentCollection );
				}
				else {
					//otherwise recreate the mapping between the collection and its key
					CollectionKey collectionKey = new CollectionKey(
							collectionEntry.getLoadedPersister(),
							collectionEntry.getLoadedKey()
					);
					persistenceContext.addCollectionByKey( collectionKey, persistentCollection );
				}
			}, true
	);
}
 
Example #4
Source File: AbstractFlushingEventListener.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * 1. Recreate the collection key -> collection map
 * 2. rebuild the collection entries
 * 3. call Interceptor.postFlush()
 */
protected void postFlush(SessionImplementor session) throws HibernateException {

	LOG.trace( "Post flush" );

	final PersistenceContext persistenceContext = session.getPersistenceContext();
	persistenceContext.getCollectionsByKey().clear();
	
	// the database has changed now, so the subselect results need to be invalidated
	// the batch fetching queues should also be cleared - especially the collection batch fetching one
	persistenceContext.getBatchFetchQueue().clear();

	for ( Map.Entry<PersistentCollection, CollectionEntry> me : IdentityMap.concurrentEntries( persistenceContext.getCollectionEntries() ) ) {
		CollectionEntry collectionEntry = me.getValue();
		PersistentCollection persistentCollection = me.getKey();
		collectionEntry.postFlush(persistentCollection);
		if ( collectionEntry.getLoadedPersister() == null ) {
			//if the collection is dereferenced, unset its session reference and remove from the session cache
			//iter.remove(); //does not work, since the entrySet is not backed by the set
			persistentCollection.unsetSession( session );
			persistenceContext.getCollectionEntries()
					.remove(persistentCollection);
		}
		else {
			//otherwise recreate the mapping between the collection and its key
			CollectionKey collectionKey = new CollectionKey(
					collectionEntry.getLoadedPersister(),
					collectionEntry.getLoadedKey()
			);
			persistenceContext.getCollectionsByKey().put(collectionKey, persistentCollection);
		}
	}

}
 
Example #5
Source File: StatefulPersistenceContext.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void addUnownedCollection(CollectionKey key, PersistentCollection collection) {
	if (unownedCollections==null) {
		unownedCollections = new HashMap<>( INIT_COLL_SIZE );
	}
	unownedCollections.put( key, collection );
}
 
Example #6
Source File: LoadContexts.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Locate the LoadingCollectionEntry within *any* of the tracked
 * {@link CollectionLoadContext}s.
 * <p/>
 * Implementation note: package protected, as this is meant solely for use
 * by {@link CollectionLoadContext} to be able to locate collections
 * being loaded by other {@link CollectionLoadContext}s/{@link ResultSet}s.
 *
 * @param key The collection key.
 * @return The located entry; or null.
 */
LoadingCollectionEntry locateLoadingCollectionEntry(CollectionKey key) {
	if ( xrefLoadingCollectionEntries == null ) {
		return null;
	}
	LOG.tracev( "Attempting to locate loading collection entry [{0}] in any result-set context", key );
	final LoadingCollectionEntry rtn = xrefLoadingCollectionEntries.get( key );
	if ( rtn == null ) {
		LOG.tracev( "Collection [{0}] not located in load context", key );
	}
	else {
		LOG.tracev( "Collection [{0}] located in load context", key );
	}
	return rtn;
}
 
Example #7
Source File: LoadContexts.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Attempt to locate the loading collection given the owner's key.  The lookup here
 * occurs against all result-set contexts...
 *
 * @param persister The collection persister
 * @param ownerKey The owner key
 * @return The loading collection, or null if not found.
 */
public PersistentCollection locateLoadingCollection(CollectionPersister persister, Serializable ownerKey) {
	final LoadingCollectionEntry lce = locateLoadingCollectionEntry( new CollectionKey( persister, ownerKey ) );
	if ( lce != null ) {
		if ( LOG.isTraceEnabled() ) {
			LOG.tracef(
					"Returning loading collection: %s",
					MessageHelper.collectionInfoString( persister, ownerKey, getSession().getFactory() )
			);
		}
		return lce.getCollection();
	}
	return null;
}
 
Example #8
Source File: CollectionType.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * instantiate a collection wrapper (called when loading an object)
 *
 * @param key The collection owner key
 * @param session The session from which the request is originating.
 * @param owner The collection owner
 * @return The collection
 */
public Object getCollection(Serializable key, SharedSessionContractImplementor session, Object owner, Boolean overridingEager) {

	CollectionPersister persister = getPersister( session );
	final PersistenceContext persistenceContext = session.getPersistenceContext();
	final EntityMode entityMode = persister.getOwnerEntityPersister().getEntityMode();

	// check if collection is currently being loaded
	PersistentCollection collection = persistenceContext.getLoadContexts().locateLoadingCollection( persister, key );

	if ( collection == null ) {

		// check if it is already completely loaded, but unowned
		collection = persistenceContext.useUnownedCollection( new CollectionKey(persister, key, entityMode) );

		if ( collection == null ) {

			collection = persistenceContext.getCollection( new CollectionKey(persister, key, entityMode) );

			if ( collection == null ) {
				// create a new collection wrapper, to be initialized later
				collection = instantiate( session, persister, key );

				collection.setOwner( owner );

				persistenceContext.addUninitializedCollection( persister, collection, key );

				// some collections are not lazy:
				boolean eager = overridingEager != null ? overridingEager : !persister.isLazy();
				if ( initializeImmediately() ) {
					session.initializeCollection( collection, false );
				}
				else if ( eager ) {
					persistenceContext.addNonLazyCollection( collection );
				}

				if ( hasHolder() ) {
					session.getPersistenceContext().addCollectionHolder( collection );
				}
			}

		}

		if ( LOG.isTraceEnabled() ) {
			LOG.tracef( "Created collection wrapper: %s",
					MessageHelper.collectionInfoString( persister, collection,
							key, session ) );
		}

	}

	collection.setOwner(owner);

	return collection.getValue();
}
 
Example #9
Source File: CoreMessageLogger.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
@LogMessage(level = WARN)
@Message(value = "In CollectionLoadContext#endLoadingCollections, localLoadingCollectionKeys contained [%s], but no LoadingCollectionEntry was found in loadContexts",
		id = 159)
void loadingCollectionKeyNotFound(CollectionKey collectionKey);
 
Example #10
Source File: LoadContexts.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
void cleanupCollectionXRefs(Set<CollectionKey> entryKeys) {
	for ( CollectionKey entryKey : entryKeys ) {
		xrefLoadingCollectionEntries.remove( entryKey );
	}
}
 
Example #11
Source File: CollectionLoadContext.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Finish the process of collection-loading for this bound result set.  Mainly this
 * involves cleaning up resources and notifying the collections that loading is
 * complete.
 *
 * @param persister The persister for which to complete loading.
 */
public void endLoadingCollections(CollectionPersister persister) {
	final SharedSessionContractImplementor session = getLoadContext().getPersistenceContext().getSession();
	if ( !loadContexts.hasLoadingCollectionEntries()
			&& localLoadingCollectionKeys.isEmpty() ) {
		return;
	}

	// in an effort to avoid concurrent-modification-exceptions (from
	// potential recursive calls back through here as a result of the
	// eventual call to PersistentCollection#endRead), we scan the
	// internal loadingCollections map for matches and store those matches
	// in a temp collection.  the temp collection is then used to "drive"
	// the #endRead processing.
	List<LoadingCollectionEntry> matches = null;
	final Iterator itr = localLoadingCollectionKeys.iterator();
	while ( itr.hasNext() ) {
		final CollectionKey collectionKey = (CollectionKey) itr.next();
		final LoadingCollectionEntry lce = loadContexts.locateLoadingCollectionEntry( collectionKey );
		if ( lce == null ) {
			LOG.loadingCollectionKeyNotFound( collectionKey );
		}
		else if ( lce.getResultSet() == resultSet && lce.getPersister() == persister ) {
			if ( matches == null ) {
				matches = new ArrayList<>();
			}
			matches.add( lce );
			if ( lce.getCollection().getOwner() == null ) {
				session.getPersistenceContext().addUnownedCollection(
						new CollectionKey(
								persister,
								lce.getKey(),
								persister.getOwnerEntityPersister().getEntityMetamodel().getEntityMode()
						),
						lce.getCollection()
				);
			}
			LOG.tracev( "Removing collection load entry [{0}]", lce );

			// todo : i'd much rather have this done from #endLoadingCollection(CollectionPersister,LoadingCollectionEntry)...
			loadContexts.unregisterLoadingCollectionXRef( collectionKey );
			itr.remove();
		}
	}

	endLoadingCollections( persister, matches );
	if ( localLoadingCollectionKeys.isEmpty() ) {
		// todo : hack!!!
		// NOTE : here we cleanup the load context when we have no more local
		// LCE entries.  This "works" for the time being because really
		// only the collection load contexts are implemented.  Long term,
		// this cleanup should become part of the "close result set"
		// processing from the (sandbox/jdbc) jdbc-container code.
		loadContexts.cleanup( resultSet );
	}
}
 
Example #12
Source File: CollectionLoadContext.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Retrieve the collection that is being loaded as part of processing this
 * result set.
 * <p/>
 * Basically, there are two valid return values from this method:<ul>
 * <li>an instance of {@link org.hibernate.collection.spi.PersistentCollection} which indicates to
 * continue loading the result set row data into that returned collection
 * instance; this may be either an instance already associated and in the
 * midst of being loaded, or a newly instantiated instance as a matching
 * associated collection was not found.</li>
 * <li><i>null</i> indicates to ignore the corresponding result set row
 * data relating to the requested collection; this indicates that either
 * the collection was found to already be associated with the persistence
 * context in a fully loaded state, or it was found in a loading state
 * associated with another result set processing context.</li>
 * </ul>
 *
 * @param persister The persister for the collection being requested.
 * @param key The key of the collection being requested.
 *
 * @return The loading collection (see discussion above).
 */
public PersistentCollection getLoadingCollection(final CollectionPersister persister, final Serializable key) {
	final EntityMode em = persister.getOwnerEntityPersister().getEntityMetamodel().getEntityMode();
	final CollectionKey collectionKey = new CollectionKey( persister, key, em );
	if ( LOG.isTraceEnabled() ) {
		LOG.tracev( "Starting attempt to find loading collection [{0}]",
				MessageHelper.collectionInfoString( persister.getRole(), key ) );
	}
	final LoadingCollectionEntry loadingCollectionEntry = loadContexts.locateLoadingCollectionEntry( collectionKey );
	if ( loadingCollectionEntry == null ) {
		// look for existing collection as part of the persistence context
		PersistentCollection collection = loadContexts.getPersistenceContext().getCollection( collectionKey );
		if ( collection != null ) {
			if ( collection.wasInitialized() ) {
				LOG.trace( "Collection already initialized; ignoring" );
				// ignore this row of results! Note the early exit
				return null;
			}
			LOG.trace( "Collection not yet initialized; initializing" );
		}
		else {
			final Object owner = loadContexts.getPersistenceContext().getCollectionOwner( key, persister );
			final boolean newlySavedEntity = owner != null
					&& loadContexts.getPersistenceContext().getEntry( owner ).getStatus() != Status.LOADING;
			if ( newlySavedEntity ) {
				// important, to account for newly saved entities in query
				// todo : some kind of check for new status...
				LOG.trace( "Owning entity already loaded; ignoring" );
				return null;
			}
			// create one
			LOG.tracev( "Instantiating new collection [key={0}, rs={1}]", key, resultSet );
			collection = persister.getCollectionType().instantiate(
					loadContexts.getPersistenceContext().getSession(), persister, key );
		}
		collection.beforeInitialize( persister, -1 );
		collection.beginRead();
		localLoadingCollectionKeys.add( collectionKey );
		loadContexts.registerLoadingCollectionXRef( collectionKey, new LoadingCollectionEntry( resultSet, persister, key, collection ) );
		return collection;
	}
	if ( loadingCollectionEntry.getResultSet() == resultSet ) {
		LOG.trace( "Found loading collection bound to current result set processing; reading row" );
		return loadingCollectionEntry.getCollection();
	}
	// ignore this row, the collection is in process of
	// being loaded somewhere further "up" the stack
	LOG.trace( "Collection is already being initialized; ignoring row" );
	return null;
}
 
Example #13
Source File: StatefulPersistenceContext.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
@Override
public PersistentCollection getCollection(CollectionKey collectionKey) {
	return collectionsByKey.get( collectionKey );
}
 
Example #14
Source File: StatefulPersistenceContext.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
@Override
public PersistentCollection useUnownedCollection(CollectionKey key) {
	return ( unownedCollections == null ) ? null : unownedCollections.remove( key );
}
 
Example #15
Source File: J2CacheMessageLogger_$logger.java    From J2Cache with Apache License 2.0 4 votes vote down vote up
public final void loadingCollectionKeyNotFound(CollectionKey arg0) {
    super.log.logf(FQCN, Logger.Level.WARN, (Throwable)null, this.loadingCollectionKeyNotFound$str(), arg0);
}
 
Example #16
Source File: J2CacheMessageLogger_$logger.java    From J2Cache with Apache License 2.0 4 votes vote down vote up
public final void loadingCollectionKeyNotFound(final CollectionKey arg0) {
    super.log.logf(FQCN, (org.jboss.logging.Logger.Level.WARN), null, loadingCollectionKeyNotFound$str(), arg0);
}
 
Example #17
Source File: LoadContexts.java    From lams with GNU General Public License v2.0 3 votes vote down vote up
/**
 * Register a loading collection xref.
 * <p/>
 * This xref map is used because sometimes a collection is in process of
 * being loaded from one result set, but needs to be accessed from the
 * context of another "nested" result set processing.
 * <p/>
 * Implementation note: package protected, as this is meant solely for use
 * by {@link CollectionLoadContext} to be able to locate collections
 * being loaded by other {@link CollectionLoadContext}s/{@link ResultSet}s.
 *
 * @param entryKey The xref collection key
 * @param entry The corresponding loading collection entry
 */
void registerLoadingCollectionXRef(CollectionKey entryKey, LoadingCollectionEntry entry) {
	if ( xrefLoadingCollectionEntries == null ) {
		xrefLoadingCollectionEntries = new HashMap<CollectionKey,LoadingCollectionEntry>();
	}
	xrefLoadingCollectionEntries.put( entryKey, entry );
}
 
Example #18
Source File: LoadContexts.java    From lams with GNU General Public License v2.0 3 votes vote down vote up
/**
 * The inverse of {@link #registerLoadingCollectionXRef}.  Here, we are done
 * processing the said collection entry, so we remove it from the
 * load context.
 * <p/>
 * The idea here is that other loading collections can now reference said
 * collection directly from the {@link PersistenceContext} because it
 * has completed its load cycle.
 * <p/>
 * Implementation note: package protected, as this is meant solely for use
 * by {@link CollectionLoadContext} to be able to locate collections
 * being loaded by other {@link CollectionLoadContext}s/{@link ResultSet}s.
 *
 * @param key The key of the collection we are done processing.
 */
void unregisterLoadingCollectionXRef(CollectionKey key) {
	if ( !hasRegisteredLoadingCollectionEntries() ) {
		return;
	}
	xrefLoadingCollectionEntries.remove( key );
}