org.hibernate.cache.spi.access.SoftLock#org.hibernate.event.spi.LoadEventListener源码实例Demo

下面列出了org.hibernate.cache.spi.access.SoftLock#org.hibernate.event.spi.LoadEventListener 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

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 );
	}
}
 
源代码2 项目: lams   文件: SessionImpl.java
@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;
	}
}
 
源代码3 项目: lams   文件: SessionImpl.java
/**
 * 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;
}
 
源代码4 项目: lams   文件: DefaultLoadEventListener.java
/**
 * 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 );
}
 
源代码5 项目: lams   文件: DefaultLoadEventListener.java
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 ) );
}
 
/**
 * 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;
					} ));
}
 
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() );
}
 
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 );
}
 
/**
 * 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 ) );
}
 
/**
 * 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 );
}
 
源代码11 项目: lams   文件: SessionImpl.java
@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;
}
 
源代码12 项目: lams   文件: SessionImpl.java
private void fireLoad(LoadEvent event, LoadType loadType) {
	checkOpenOrWaitingForAutoClose();
	checkTransactionSynchStatus();
	for ( LoadEventListener listener : listeners( EventType.LOAD ) ) {
		listener.onLoad( event, loadType );
	}
	delayedAfterCompletion();
}
 
源代码13 项目: lams   文件: DefaultLoadEventListener.java
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;
	}
}
 
源代码14 项目: lams   文件: DefaultLoadEventListener.java
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()
		);
}
 
源代码15 项目: lams   文件: DefaultLoadEventListener.java
/**
 * 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;
}
 
源代码16 项目: lams   文件: DefaultLoadEventListener.java
/**
 * 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 );
}
 
源代码17 项目: lams   文件: DefaultLoadEventListener.java
/**
 * 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 );
}
 
源代码18 项目: lams   文件: DefaultLoadEventListener.java
/**
 * 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;
}
 
源代码19 项目: lams   文件: DefaultLoadEventListener.java
/**
 * 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 );
}
 
源代码20 项目: lams   文件: DefaultLoadEventListener.java
/**
 * 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;
}
 
源代码21 项目: hibernate-reactive   文件: ReactiveSessionImpl.java
private CompletionStage<Void> fireLoad(LoadEvent event, LoadEventListener.LoadType loadType) {
	checkOpenOrWaitingForAutoClose();

	return fireLoadNoChecks( event, loadType )
			.whenComplete( (v, e) -> delayedAfterCompletion() );
}
 
源代码22 项目: hibernate-reactive   文件: ReactiveSessionImpl.java
private CompletionStage<Void> fireLoadNoChecks(LoadEvent event, LoadEventListener.LoadType loadType) {
	pulseTransactionCoordinator();

	return fire(event, loadType, EventType.LOAD, (ReactiveLoadEventListener l) -> l::reactiveOnLoad);
}
 
源代码23 项目: hibernate-reactive   文件: ReactiveSessionImpl.java
public final CompletionStage<T> load(Serializable id) {
	return perform( () -> doLoad( id, LoadEventListener.GET) );
}
 
源代码24 项目: hibernate-reactive   文件: ReactiveSessionImpl.java
public final CompletionStage<T> fetch(Serializable id) {
	return perform( () -> doLoad( id, LoadEventListener.IMMEDIATE_LOAD) );
}
 
/**
 * 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" );
	}
}
 
/**
 * 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;
	}
}
 
/**
 * 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;
				} );
	}
}
 
源代码28 项目: lams   文件: DefaultLoadEventListener.java
/**
 * 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;
}