org.hibernate.event.spi.LoadEventListener Java Examples

The following examples show how to use org.hibernate.event.spi.LoadEventListener. 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: DefaultReactiveLoadEventListener.java    From hibernate-reactive with GNU Lesser General Public License v2.1 6 votes vote down vote up
private CompletionStage<Object> doOnLoad(
		final EntityPersister persister,
		final LoadEvent event,
		final LoadEventListener.LoadType loadType) {

	final EventSource session = event.getSession();
	final EntityKey keyToLoad = session.generateEntityKey( event.getEntityId(), persister );
	if ( loadType.isNakedEntityReturned() ) {
		//do not return a proxy!
		//(this option indicates we are initializing a proxy)
		return load( event, persister, keyToLoad, loadType );
	}
	//return a proxy if appropriate
	else if ( event.getLockMode() == LockMode.NONE ) {
		return proxyOrLoad( event, persister, keyToLoad, loadType );
	}
	else {
		return lockAndLoad( event, persister, keyToLoad, loadType, session );
	}
}
 
Example #2
Source File: DefaultLoadEventListener.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
private void loadByDerivedIdentitySimplePkValue(
		LoadEvent event,
		LoadEventListener.LoadType options,
		EntityPersister dependentPersister,
		EmbeddedComponentType dependentIdType,
		EntityPersister parentPersister) {
	final EntityKey parentEntityKey = event.getSession().generateEntityKey( event.getEntityId(), parentPersister );
	final Object parent = doLoad( event, parentPersister, parentEntityKey, options );

	final Serializable dependent = (Serializable) dependentIdType.instantiate( parent, event.getSession() );
	dependentIdType.setPropertyValues( dependent, new Object[] {parent}, dependentPersister.getEntityMode() );
	final EntityKey dependentEntityKey = event.getSession().generateEntityKey( dependent, dependentPersister );
	event.setEntityId( dependent );

	event.setResult( doLoad( event, dependentPersister, dependentEntityKey, options ) );
}
 
Example #3
Source File: DefaultLoadEventListener.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Handle the given load event.
 *
 * @param event The load event to be handled.
 *
 * @throws HibernateException
 */
public void onLoad(
		final LoadEvent event,
		final LoadEventListener.LoadType loadType) throws HibernateException {

	final EntityPersister persister = getPersister( event );

	if ( persister == null ) {
		throw new HibernateException( "Unable to locate persister: " + event.getEntityClassName() );
	}

	final Class idClass = persister.getIdentifierType().getReturnedClass();
	if ( idClass != null &&
			!idClass.isInstance( event.getEntityId() ) &&
			!DelayedPostInsertIdentifier.class.isInstance( event.getEntityId() ) ) {
		checkIdClass( persister, event, loadType, idClass );
	}

	doOnLoad( persister, event, loadType );
}
 
Example #4
Source File: SessionImpl.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
@Override
public void load(Object object, Serializable id) throws HibernateException {
	LoadEvent event = loadEvent;
	loadEvent = null;
	if ( event == null ) {
		event = new LoadEvent( id, object, this );
	}
	else {
		event.setEntityClassName( null );
		event.setEntityId( id );
		event.setInstanceToLoad( object );
		event.setLockMode( LoadEvent.DEFAULT_LOCK_MODE );
		event.setLockScope( LoadEvent.DEFAULT_LOCK_OPTIONS.getScope() );
		event.setLockTimeout( LoadEvent.DEFAULT_LOCK_OPTIONS.getTimeOut() );
	}

	fireLoad( event, LoadEventListener.RELOAD );

	if ( loadEvent == null ) {
		event.setEntityClassName( null );
		event.setEntityId( null );
		event.setInstanceToLoad( null );
		event.setResult( null );
		loadEvent = event;
	}
}
 
Example #5
Source File: SessionImpl.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Load the data for the object with the specified id into a newly created object.
 * This is only called when lazily initializing a proxy.
 * Do NOT return a proxy.
 */
@Override
public Object immediateLoad(String entityName, Serializable id) throws HibernateException {
	if ( log.isDebugEnabled() ) {
		EntityPersister persister = getFactory().getMetamodel().entityPersister( entityName );
		log.debugf( "Initializing proxy: %s", MessageHelper.infoString( persister, id, getFactory() ) );
	}
	LoadEvent event = loadEvent;
	loadEvent = null;
	event = recycleEventInstance( event, id, entityName );
	fireLoad( event, LoadEventListener.IMMEDIATE_LOAD );
	Object result = event.getResult();
	if ( loadEvent == null ) {
		event.setEntityClassName( null );
		event.setEntityId( null );
		event.setInstanceToLoad( null );
		event.setResult( null );
		loadEvent = event;
	}
	return result;
}
 
Example #6
Source File: DefaultLoadEventListener.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Attempts to locate the entity in the session-level cache.
 * <p/>
 * If allowed to return nulls, then if the entity happens to be found in
 * the session cache, we check the entity type for proper handling
 * of entity hierarchies.
 * <p/>
 * If checkDeleted was set to true, then if the entity is found in the
 * session-level cache, it's current status within the session cache
 * is checked to see if it has previously been scheduled for deletion.
 *
 * @param event The load event
 * @param keyToLoad The EntityKey representing the entity to be loaded.
 * @param options The load options.
 *
 * @return The entity from the session-level cache, or null.
 *
 * @throws HibernateException Generally indicates problems applying a lock-mode.
 */
protected Object loadFromSessionCache(
		final LoadEvent event,
		final EntityKey keyToLoad,
		final LoadEventListener.LoadType options) throws HibernateException {

	SessionImplementor session = event.getSession();
	Object old = session.getEntityUsingInterceptor( keyToLoad );

	if ( old != null ) {
		// this object was already loaded
		EntityEntry oldEntry = session.getPersistenceContext().getEntry( old );
		if ( options.isCheckDeleted() ) {
			Status status = oldEntry.getStatus();
			if ( status == Status.DELETED || status == Status.GONE ) {
				return REMOVED_ENTITY_MARKER;
			}
		}
		if ( options.isAllowNulls() ) {
			final EntityPersister persister = event.getSession()
					.getFactory()
					.getEntityPersister( keyToLoad.getEntityName() );
			if ( !persister.isInstance( old ) ) {
				return INCONSISTENT_RTN_CLASS_MARKER;
			}
		}
		upgradeLock( old, oldEntry, event.getLockOptions(), event.getSession() );
	}

	return old;
}
 
Example #7
Source File: DefaultLoadEventListener.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * If the class to be loaded has been configured with a cache, then lock
 * given id in that cache and then perform the load.
 *
 * @param event The initiating load request event
 * @param persister The persister corresponding to the entity to be loaded
 * @param keyToLoad The key of the entity to be loaded
 * @param options The defined load options
 * @param source The originating session
 *
 * @return The loaded entity
 *
 * @throws HibernateException
 */
private Object lockAndLoad(
		final LoadEvent event,
		final EntityPersister persister,
		final EntityKey keyToLoad,
		final LoadEventListener.LoadType options,
		final SessionImplementor source) {
	SoftLock lock = null;
	final Object ck;
	final EntityDataAccess cache = persister.getCacheAccessStrategy();
	if ( persister.canWriteToCache() ) {
		ck = cache.generateCacheKey(
				event.getEntityId(),
				persister,
				source.getFactory(),
				source.getTenantIdentifier()
		);
		lock = persister.getCacheAccessStrategy().lockItem( source, ck, null );
	}
	else {
		ck = null;
	}

	Object entity;
	try {
		entity = load( event, persister, keyToLoad, options );
	}
	finally {
		if ( persister.canWriteToCache() ) {
			cache.unlockItem( source, ck, lock );
		}
	}

	return event.getSession().getPersistenceContext().proxyFor( persister, keyToLoad, entity );
}
 
Example #8
Source File: DefaultLoadEventListener.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * If there is already a corresponding proxy associated with the
 * persistence context, return it; otherwise create a proxy, associate it
 * with the persistence context, and return the just-created proxy.
 *
 * @param event The initiating load request event
 * @param persister The persister corresponding to the entity to be loaded
 * @param keyToLoad The key of the entity to be loaded
 * @param options The defined load options
 * @param persistenceContext The originating session
 *
 * @return The created/existing proxy
 */
private Object createProxyIfNecessary(
		final LoadEvent event,
		final EntityPersister persister,
		final EntityKey keyToLoad,
		final LoadEventListener.LoadType options,
		final PersistenceContext persistenceContext) {
	Object existing = persistenceContext.getEntity( keyToLoad );
	if ( existing != null ) {
		// return existing object or initialized proxy (unless deleted)
		if ( traceEnabled ) {
			LOG.trace( "Entity found in session cache" );
		}
		if ( options.isCheckDeleted() ) {
			EntityEntry entry = persistenceContext.getEntry( existing );
			Status status = entry.getStatus();
			if ( status == Status.DELETED || status == Status.GONE ) {
				return null;
			}
		}
		return existing;
	}
	if ( traceEnabled ) {
		LOG.trace( "Creating new proxy for entity" );
	}
	// return new uninitialized proxy
	Object proxy = persister.createProxy( event.getEntityId(), event.getSession() );
	persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey( keyToLoad );
	persistenceContext.addProxy( keyToLoad, proxy );
	return proxy;
}
 
Example #9
Source File: DefaultLoadEventListener.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Given a proxy, initialize it and/or narrow it provided either
 * is necessary.
 *
 * @param event The initiating load request event
 * @param persister The persister corresponding to the entity to be loaded
 * @param keyToLoad The key of the entity to be loaded
 * @param options The defined load options
 * @param persistenceContext The originating session
 * @param proxy The proxy to narrow
 *
 * @return The created/existing proxy
 */
private Object returnNarrowedProxy(
		final LoadEvent event,
		final EntityPersister persister,
		final EntityKey keyToLoad,
		final LoadEventListener.LoadType options,
		final PersistenceContext persistenceContext,
		final Object proxy) {
	if ( traceEnabled ) {
		LOG.trace( "Entity proxy found in session cache" );
	}
	LazyInitializer li = ( (HibernateProxy) proxy ).getHibernateLazyInitializer();
	if ( li.isUnwrap() ) {
		return li.getImplementation();
	}
	Object impl = null;
	if ( !options.isAllowProxyCreation() ) {
		impl = load( event, persister, keyToLoad, options );
		if ( impl == null ) {
			event.getSession()
					.getFactory()
					.getEntityNotFoundDelegate()
					.handleEntityNotFound( persister.getEntityName(), keyToLoad.getIdentifier() );
		}
	}
	return persistenceContext.narrowProxy( proxy, persister, keyToLoad, impl );
}
 
Example #10
Source File: DefaultLoadEventListener.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Based on configured options, will either return a pre-existing proxy,
 * generate a new proxy, or perform an actual load.
 *
 * @param event The initiating load request event
 * @param persister The persister corresponding to the entity to be loaded
 * @param keyToLoad The key of the entity to be loaded
 * @param options The defined load options
 *
 * @return The result of the proxy/load operation.
 */
private Object proxyOrLoad(
		final LoadEvent event,
		final EntityPersister persister,
		final EntityKey keyToLoad,
		final LoadEventListener.LoadType options) {

	if ( traceEnabled ) {
		LOG.tracev(
				"Loading entity: {0}",
				MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
		);
	}

	// this class has no proxies (so do a shortcut)
	if ( !persister.hasProxy() ) {
		return load( event, persister, keyToLoad, options );
	}

	final PersistenceContext persistenceContext = event.getSession().getPersistenceContext();

	// look for a proxy
	Object proxy = persistenceContext.getProxy( keyToLoad );
	if ( proxy != null ) {
		return returnNarrowedProxy( event, persister, keyToLoad, options, persistenceContext, proxy );
	}

	if ( options.isAllowProxyCreation() ) {
		return createProxyIfNecessary( event, persister, keyToLoad, options, persistenceContext );
	}

	// return a newly loaded object
	return load( event, persister, keyToLoad, options );
}
 
Example #11
Source File: DefaultLoadEventListener.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Performs the load of an entity.
 *
 * @param event The initiating load request event
 * @param persister The persister corresponding to the entity to be loaded
 * @param keyToLoad The key of the entity to be loaded
 * @param options The defined load options
 *
 * @return The loaded entity.
 *
 * @throws HibernateException
 */
private Object load(
		final LoadEvent event,
		final EntityPersister persister,
		final EntityKey keyToLoad,
		final LoadEventListener.LoadType options) {

	if ( event.getInstanceToLoad() != null ) {
		if ( event.getSession().getPersistenceContext().getEntry( event.getInstanceToLoad() ) != null ) {
			throw new PersistentObjectException(
					"attempted to load into an instance that was already associated with the session: " +
							MessageHelper.infoString(
									persister,
									event.getEntityId(),
									event.getSession().getFactory()
							)
			);
		}
		persister.setIdentifier( event.getInstanceToLoad(), event.getEntityId(), event.getSession() );
	}

	final Object entity = doLoad( event, persister, keyToLoad, options );

	boolean isOptionalInstance = event.getInstanceToLoad() != null;

	if ( entity == null && ( !options.isAllowNulls() || isOptionalInstance ) ) {
		event.getSession()
				.getFactory()
				.getEntityNotFoundDelegate()
				.handleEntityNotFound( event.getEntityClassName(), event.getEntityId() );
	}
	else if ( isOptionalInstance && entity != event.getInstanceToLoad() ) {
		throw new NonUniqueObjectException( event.getEntityId(), event.getEntityClassName() );
	}

	return entity;
}
 
Example #12
Source File: DefaultLoadEventListener.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private void checkIdClass(
		final EntityPersister persister,
		final LoadEvent event,
		final LoadEventListener.LoadType loadType,
		final Class idClass) {
			// we may have the kooky jpa requirement of allowing find-by-id where
		// "id" is the "simple pk value" of a dependent objects parent.  This
		// is part of its generally goofy "derived identity" "feature"
		if ( persister.getEntityMetamodel().getIdentifierProperty().isEmbedded() ) {
			final EmbeddedComponentType dependentIdType =
					(EmbeddedComponentType) persister.getEntityMetamodel().getIdentifierProperty().getType();
			if ( dependentIdType.getSubtypes().length == 1 ) {
				final Type singleSubType = dependentIdType.getSubtypes()[0];
				if ( singleSubType.isEntityType() ) {
					final EntityType dependentParentType = (EntityType) singleSubType;
					final Type dependentParentIdType = dependentParentType.getIdentifierOrUniqueKeyType( event.getSession().getFactory() );
					if ( dependentParentIdType.getReturnedClass().isInstance( event.getEntityId() ) ) {
						// yep that's what we have...
						loadByDerivedIdentitySimplePkValue(
								event,
								loadType,
								persister,
								dependentIdType,
								event.getSession().getFactory().getEntityPersister( dependentParentType.getAssociatedEntityName() )
						);
						return;
					}
				}
			}
		}
		throw new TypeMismatchException(
				"Provided id of the wrong type for class " + persister.getEntityName() + ". Expected: " + idClass
						+ ", got " + event.getEntityId().getClass()
		);
}
 
Example #13
Source File: DefaultLoadEventListener.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private void doOnLoad(
		final EntityPersister persister,
		final LoadEvent event,
		final LoadEventListener.LoadType loadType) {

	try {
		final EntityKey keyToLoad = event.getSession().generateEntityKey( event.getEntityId(), persister );
		if ( loadType.isNakedEntityReturned() ) {
			//do not return a proxy!
			//(this option indicates we are initializing a proxy)
			event.setResult( load( event, persister, keyToLoad, loadType ) );
		}
		else {
			//return a proxy if appropriate
			if ( event.getLockMode() == LockMode.NONE ) {
				event.setResult( proxyOrLoad( event, persister, keyToLoad, loadType ) );
			}
			else {
				event.setResult( lockAndLoad( event, persister, keyToLoad, loadType, event.getSession() ) );
			}
		}
	}
	catch (HibernateException e) {
		LOG.unableToLoadCommand( e );
		throw e;
	}
}
 
Example #14
Source File: SessionImpl.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private void fireLoad(LoadEvent event, LoadType loadType) {
	checkOpenOrWaitingForAutoClose();
	checkTransactionSynchStatus();
	for ( LoadEventListener listener : listeners( EventType.LOAD ) ) {
		listener.onLoad( event, loadType );
	}
	delayedAfterCompletion();
}
 
Example #15
Source File: SessionImpl.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@Override
public final Object internalLoad(String entityName, Serializable id, boolean eager, boolean nullable)
		throws HibernateException {
	// todo : remove
	LoadEventListener.LoadType type = nullable
			? LoadEventListener.INTERNAL_LOAD_NULLABLE
			: eager
			? LoadEventListener.INTERNAL_LOAD_EAGER
			: LoadEventListener.INTERNAL_LOAD_LAZY;

	LoadEvent event = loadEvent;
	loadEvent = null;
	event = recycleEventInstance( event, id, entityName );
	fireLoad( event, type );
	Object result = event.getResult();
	if ( !nullable ) {
		UnresolvableObjectException.throwIfNull( result, id, entityName );
	}
	if ( loadEvent == null ) {
		event.setEntityClassName( null );
		event.setEntityId( null );
		event.setInstanceToLoad( null );
		event.setResult( null );
		loadEvent = event;
	}
	return result;
}
 
Example #16
Source File: DefaultReactiveLoadEventListener.java    From hibernate-reactive with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * If there is already a corresponding proxy associated with the
 * persistence context, return it; otherwise create a proxy, associate it
 * with the persistence context, and return the just-created proxy.
 *
 * @param event The initiating load request event
 * @param persister The persister corresponding to the entity to be loaded
 * @param keyToLoad The key of the entity to be loaded
 * @param options The defined load options
 * @param persistenceContext The originating session
 *
 * @return The created/existing proxy
 */
private Object createProxyIfNecessary(
		final LoadEvent event,
		final EntityPersister persister,
		final EntityKey keyToLoad,
		final LoadEventListener.LoadType options,
		final PersistenceContext persistenceContext) {
	Object existing = persistenceContext.getEntity( keyToLoad );
	final boolean traceEnabled = LOG.isTraceEnabled();
	if ( existing != null ) {
		// return existing object or initialized proxy (unless deleted)
		if ( traceEnabled ) {
			LOG.trace( "Entity found in session cache" );
		}
		if ( options.isCheckDeleted() ) {
			EntityEntry entry = persistenceContext.getEntry( existing );
			Status status = entry.getStatus();
			if ( status == Status.DELETED || status == Status.GONE ) {
				return null;
			}
		}
		return existing;
	}
	if ( traceEnabled ) {
		LOG.trace( "Creating new proxy for entity" );
	}
	return createProxy( event, persister, keyToLoad, persistenceContext );
}
 
Example #17
Source File: DefaultReactiveLoadEventListener.java    From hibernate-reactive with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Given a proxy, initialize it and/or narrow it provided either
 * is necessary.
 *
 * @param event The initiating load request event
 * @param persister The persister corresponding to the entity to be loaded
 * @param keyToLoad The key of the entity to be loaded
 * @param options The defined load options
 * @param persistenceContext The originating session
 * @param proxy The proxy to narrow
 *
 * @return The created/existing proxy
 */
private CompletionStage<Object> returnNarrowedProxy(
		final LoadEvent event,
		final EntityPersister persister,
		final EntityKey keyToLoad,
		final LoadEventListener.LoadType options,
		final PersistenceContext persistenceContext,
		final Object proxy) {
	if ( LOG.isTraceEnabled() ) {
		LOG.trace( "Entity proxy found in session cache" );
	}

	LazyInitializer li = ( (HibernateProxy) proxy ).getHibernateLazyInitializer();

	if ( li.isUnwrap() ) {
		return CompletionStages.completedFuture( li.getImplementation() );
	}

	CompletionStage<Object> implStage;
	if ( !options.isAllowProxyCreation() ) {
		implStage = load( event, persister, keyToLoad, options )
				.thenApply( optional -> {
					if ( optional == null ) {
						event.getSession()
								.getFactory()
								.getEntityNotFoundDelegate()
								.handleEntityNotFound( persister.getEntityName(), keyToLoad.getIdentifier() );
					}
					return optional;
				} );
	}
	else {
		implStage = CompletionStages.nullFuture();
	}

	return implStage.thenApply( impl -> persistenceContext.narrowProxy( proxy, persister, keyToLoad, impl ) );
}
 
Example #18
Source File: DefaultReactiveLoadEventListener.java    From hibernate-reactive with GNU Lesser General Public License v2.1 5 votes vote down vote up
private CompletionStage<Void> loadByDerivedIdentitySimplePkValue(LoadEvent event, LoadEventListener.LoadType options,
		EntityPersister dependentPersister, EmbeddedComponentType dependentIdType, EntityPersister parentPersister) {
	EventSource session = event.getSession();
	final EntityKey parentEntityKey = session.generateEntityKey( event.getEntityId(), parentPersister );
	return doLoad( event, parentPersister, parentEntityKey, options )
			.thenApply( checkEntityFound( session, parentEntityKey.getEntityName(), parentEntityKey ) )
			.thenApply( parent -> {
				final Serializable dependent = (Serializable) dependentIdType.instantiate( parent, session );
				dependentIdType.setPropertyValues( dependent, new Object[] {parent}, dependentPersister.getEntityMode() );
				event.setEntityId( dependent );
				return session.generateEntityKey( dependent, dependentPersister );
			} )
			.thenCompose( dependentEntityKey -> doLoad( event, dependentPersister, dependentEntityKey, options ) )
			.thenAccept( event::setResult );
}
 
Example #19
Source File: DefaultReactiveLoadEventListener.java    From hibernate-reactive with GNU Lesser General Public License v2.1 5 votes vote down vote up
private CompletionStage<Void> checkIdClass(
		final EntityPersister persister,
		final LoadEvent event,
		final LoadEventListener.LoadType loadType,
		final Class<?> idClass) {
	// we may have the kooky jpa requirement of allowing find-by-id where
	// "id" is the "simple pk value" of a dependent objects parent.  This
	// is part of its generally goofy "derived identity" "feature"
	final IdentifierProperty identifierProperty = persister.getEntityMetamodel().getIdentifierProperty();
	if ( identifierProperty.isEmbedded() ) {
		final EmbeddedComponentType dependentIdType = (EmbeddedComponentType) identifierProperty.getType();
		if ( dependentIdType.getSubtypes().length == 1 ) {
			final Type singleSubType = dependentIdType.getSubtypes()[0];
			if ( singleSubType.isEntityType() ) {
				final EntityType dependentParentType = (EntityType) singleSubType;
				final SessionFactoryImplementor factory = event.getSession().getFactory();
				final Type dependentParentIdType = dependentParentType.getIdentifierOrUniqueKeyType( factory );
				if ( dependentParentIdType.getReturnedClass().isInstance( event.getEntityId() ) ) {
					// yep that's what we have...
					return loadByDerivedIdentitySimplePkValue( event, loadType, persister,
							dependentIdType, factory.getMetamodel().entityPersister( dependentParentType.getAssociatedEntityName() )
					);
				}
			}
		}
	}
	throw new TypeMismatchException(
			"Provided id of the wrong type for class " + persister.getEntityName() + ". Expected: " + idClass + ", got " + event.getEntityId().getClass() );
}
 
Example #20
Source File: DefaultReactiveLoadEventListener.java    From hibernate-reactive with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Handle the given load event.
 *
 * @param event The load event to be handled.
 */
@Override
public CompletionStage<Void> reactiveOnLoad(
		final LoadEvent event,
		final LoadEventListener.LoadType loadType) throws HibernateException {

	final EntityPersister persister = getPersister( event );

	if ( persister == null ) {
		throw new HibernateException( "Unable to locate persister: " + event.getEntityClassName() );
	}

	return checkId( event, loadType, persister ).thenCompose(
			vd -> doOnLoad( persister, event, loadType )
					.thenAccept( event::setResult )
					.handle( (v, x) -> {
						if ( x instanceof HibernateException ) {
							LOG.unableToLoadCommand( (HibernateException) x );
						}
						CompletionStages.returnNullorRethrow( x );

						if ( event.getResult() instanceof CompletionStage ) {
							throw new AssertionFailure( "Unexpected CompletionStage" );
						}

						return v;
					} ));
}
 
Example #21
Source File: DefaultReactiveLoadEventListener.java    From hibernate-reactive with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * Coordinates the efforts to load a given entity.  First, an attempt is
 * made to load the entity from the session-level cache.  If not found there,
 * an attempt is made to locate it in second-level cache.  Lastly, an
 * attempt is made to load it directly from the datasource.
 *
 * @param event The load event
 * @param persister The persister for the entity being requested for load
 * @param keyToLoad The EntityKey representing the entity to be loaded.
 * @param options The load options.
 *
 * @return The loaded entity, or null.
 */
private CompletionStage<Object> doLoad(
		final LoadEvent event,
		final EntityPersister persister,
		final EntityKey keyToLoad,
		final LoadEventListener.LoadType options) {

	final EventSource session = event.getSession();
	final boolean traceEnabled = LOG.isTraceEnabled();
	if ( traceEnabled ) {
		LOG.tracev(
				"Attempting to resolve: {0}",
				MessageHelper.infoString( persister, event.getEntityId(), session.getFactory() )
		);
	}

	CacheEntityLoaderHelper.PersistenceContextEntry persistenceContextEntry =
			CacheEntityLoaderHelper.INSTANCE.loadFromSessionCache(
					event,
					keyToLoad,
					options
			);
	Object entity = persistenceContextEntry.getEntity();
	if ( entity != null ) {
		Object managed = persistenceContextEntry.isManaged() ? entity : null;
		return CompletionStages.completedFuture( managed );
	}

	entity = CacheEntityLoaderHelper.INSTANCE.loadFromSecondLevelCache( event, persister, keyToLoad );
	if ( entity != null ) {
		if ( traceEnabled ) {
			LOG.tracev(
					"Resolved object in second-level cache: {0}",
					MessageHelper.infoString( persister, event.getEntityId(), session.getFactory() )
			);
		}
		cacheNaturalId( event, persister, session, entity );
		return CompletionStages.completedFuture( entity );
	}
	else {
		if ( traceEnabled ) {
			LOG.tracev(
					"Object not resolved in any cache: {0}",
					MessageHelper.infoString( persister, event.getEntityId(), session.getFactory() )
			);
		}
		return loadFromDatasource( event, persister )
				.thenApply( optional -> {
					if ( optional!=null ) {
						cacheNaturalId( event, persister, session, optional );
					}
					return optional;
				} );
	}
}
 
Example #22
Source File: DefaultReactiveLoadEventListener.java    From hibernate-reactive with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * If the class to be loaded has been configured with a cache, then lock
 * given id in that cache and then perform the load.
 *
 * @param event The initiating load request event
 * @param persister The persister corresponding to the entity to be loaded
 * @param keyToLoad The key of the entity to be loaded
 * @param options The defined load options
 * @param source The originating session
 *
 * @return The loaded entity
 */
private CompletionStage<Object> lockAndLoad(
		final LoadEvent event,
		final EntityPersister persister,
		final EntityKey keyToLoad,
		final LoadEventListener.LoadType options,
		final SessionImplementor source) {
	final SoftLock lock;
	final Object ck;
	final EntityDataAccess cache = persister.getCacheAccessStrategy();
	final boolean canWriteToCache = persister.canWriteToCache();
	if ( canWriteToCache ) {
		ck = cache.generateCacheKey(
				event.getEntityId(),
				persister,
				source.getFactory(),
				source.getTenantIdentifier()
		);
		lock = cache.lockItem( source, ck, null );
	}
	else {
		ck = null;
		lock = null;
	}

	try {
		return load( event, persister, keyToLoad, options )
				.whenComplete( (v, x) -> {
					if ( canWriteToCache ) {
						cache.unlockItem( source, ck, lock );
					}
				} )
				.thenApply( entity -> source.getPersistenceContextInternal().proxyFor( persister, keyToLoad, entity ) );
	}
	catch (HibernateException he) {
		//in case load() throws an exception
		if ( canWriteToCache ) {
			cache.unlockItem( source, ck, lock );
		}
		throw he;
	}
}
 
Example #23
Source File: DefaultReactiveLoadEventListener.java    From hibernate-reactive with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * This method is not reactive but we expect it to be called only when a proxy can be returned.
 * <p>
 *     In particular, it should be called only by
 *     {@link org.hibernate.internal.SessionImpl#internalLoad(String, Serializable, boolean, boolean)}.
 * </p>
 *
 * @see org.hibernate.event.internal.DefaultLoadEventListener#onLoad(LoadEvent, LoadType)
 * @throws UnsupportedOperationException if the entity loaded is not a proxy
 */
@Override
public void onLoad(
		final LoadEvent event,
		final LoadEventListener.LoadType loadType) throws HibernateException {
	final EntityPersister persister = getPersister( event );

	if ( persister == null ) {
		throw new HibernateException( "Unable to locate persister: " + event.getEntityClassName() );
	}

	// Since this method is not reactive, we're not expecting to hit the
	// database here (if we do, it's a bug) and so we can assume the
	// returned CompletionStage is already completed
	CompletionStage<Void> checkId = checkId( event, loadType, persister );
	if ( !checkId.toCompletableFuture().isDone() ) {
		// This only happens if the object is loaded from the db
		throw new AssertionFailure( "Unexpected access to the database" );
	}

	try {
		// Since this method is not reactive, we're not expecting to hit the
		// database here (if we do, it's a bug) and so we can assume the
		// returned CompletionStage is already completed (a proxy, perhaps)
		CompletionStage<Object> loaded = doOnLoad( persister, event, loadType );
		if ( !loaded.toCompletableFuture().isDone() ) {
			// This only happens if the object is loaded from the db
			throw new AssertionFailure( "Unexpected access to the database" );
		}
		else {
			// Proxy
			event.setResult( loaded.toCompletableFuture().getNow( null ) );
		}
	}
	catch (HibernateException e) {
		LOG.unableToLoadCommand( e );
		throw e;
	}

	if ( event.getResult() instanceof CompletionStage ) {
		throw new AssertionFailure( "Unexpected CompletionStage" );
	}
}
 
Example #24
Source File: ReactiveSessionImpl.java    From hibernate-reactive with GNU Lesser General Public License v2.1 4 votes vote down vote up
public final CompletionStage<T> fetch(Serializable id) {
	return perform( () -> doLoad( id, LoadEventListener.IMMEDIATE_LOAD) );
}
 
Example #25
Source File: ReactiveSessionImpl.java    From hibernate-reactive with GNU Lesser General Public License v2.1 4 votes vote down vote up
public final CompletionStage<T> load(Serializable id) {
	return perform( () -> doLoad( id, LoadEventListener.GET) );
}
 
Example #26
Source File: ReactiveSessionImpl.java    From hibernate-reactive with GNU Lesser General Public License v2.1 4 votes vote down vote up
private CompletionStage<Void> fireLoadNoChecks(LoadEvent event, LoadEventListener.LoadType loadType) {
	pulseTransactionCoordinator();

	return fire(event, loadType, EventType.LOAD, (ReactiveLoadEventListener l) -> l::reactiveOnLoad);
}
 
Example #27
Source File: DefaultLoadEventListener.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Coordinates the efforts to load a given entity.  First, an attempt is
 * made to load the entity from the session-level cache.  If not found there,
 * an attempt is made to locate it in second-level cache.  Lastly, an
 * attempt is made to load it directly from the datasource.
 *
 * @param event The load event
 * @param persister The persister for the entity being requested for load
 * @param keyToLoad The EntityKey representing the entity to be loaded.
 * @param options The load options.
 *
 * @return The loaded entity, or null.
 */
private Object doLoad(
		final LoadEvent event,
		final EntityPersister persister,
		final EntityKey keyToLoad,
		final LoadEventListener.LoadType options) {

	if ( traceEnabled ) {
		LOG.tracev(
				"Attempting to resolve: {0}",
				MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
		);
	}

	Object entity = loadFromSessionCache( event, keyToLoad, options );
	if ( entity == REMOVED_ENTITY_MARKER ) {
		LOG.debug( "Load request found matching entity in context, but it is scheduled for removal; returning null" );
		return null;
	}
	if ( entity == INCONSISTENT_RTN_CLASS_MARKER ) {
		LOG.debug(
				"Load request found matching entity in context, but the matched entity was of an inconsistent return type; returning null"
		);
		return null;
	}
	if ( entity != null ) {
		if ( traceEnabled ) {
			LOG.tracev(
					"Resolved object in session cache: {0}",
					MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
			);
		}
		return entity;
	}

	entity = loadFromSecondLevelCache( event, persister, keyToLoad );
	if ( entity != null ) {
		if ( traceEnabled ) {
			LOG.tracev(
					"Resolved object in second-level cache: {0}",
					MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
			);
		}
	}
	else {
		if ( traceEnabled ) {
			LOG.tracev(
					"Object not resolved in any cache: {0}",
					MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
			);
		}
		entity = loadFromDatasource( event, persister );
	}

	if ( entity != null && persister.hasNaturalIdentifier() ) {
		event.getSession().getPersistenceContext().getNaturalIdHelper().cacheNaturalIdCrossReferenceFromLoad(
				persister,
				event.getEntityId(),
				event.getSession().getPersistenceContext().getNaturalIdHelper().extractNaturalIdValues(
						entity,
						persister
				)
		);
	}


	return entity;
}
 
Example #28
Source File: ReactiveSessionImpl.java    From hibernate-reactive with GNU Lesser General Public License v2.1 4 votes vote down vote up
private CompletionStage<Void> fireLoad(LoadEvent event, LoadEventListener.LoadType loadType) {
	checkOpenOrWaitingForAutoClose();

	return fireLoadNoChecks( event, loadType )
			.whenComplete( (v, e) -> delayedAfterCompletion() );
}