Java Code Examples for org.hibernate.event.spi.EventSource#generateEntityKey()

The following examples show how to use org.hibernate.event.spi.EventSource#generateEntityKey() . 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: 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 3
Source File: DefaultMergeEventListener.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private boolean existsInDatabase(Object entity, EventSource source, EntityPersister persister) {
	EntityEntry entry = source.getPersistenceContext().getEntry( entity );
	if ( entry == null ) {
		Serializable id = persister.getIdentifier( entity, source );
		if ( id != null ) {
			final EntityKey key = source.generateEntityKey( id, persister );
			final Object managedEntity = source.getPersistenceContext().getEntity( key );
			entry = source.getPersistenceContext().getEntry( managedEntity );
		}
	}

	return entry != null && entry.isExistsInDatabase();
}
 
Example 4
Source File: AbstractReactiveSaveEventListener.java    From hibernate-reactive with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * Prepares the save call by checking the session caches for a pre-existing
 * entity and performing any lifecycle callbacks.
 *
 * @param entity The entity to be saved.
 * @param id The id by which to save the entity.
 * @param persister The entity's persister instance.
 * @param useIdentityColumn Is an identity column being used?
 * @param context Generally cascade-specific information.
 * @param source The session from which the event originated.
 * @param requiresImmediateIdAccess does the event context require
 * access to the identifier immediately after execution of this method (if
 * not, post-insert style id generators may be postponed if we are outside
 * a transaction).
 *
 * @return The id used to save the entity; may be null depending on the
 * type of id generator used and the requiresImmediateIdAccess value
 */
protected CompletionStage<Void> reactivePerformSave(
		Object entity,
		Serializable id,
		EntityPersister persister,
		boolean useIdentityColumn,
		C context,
		EventSource source,
		boolean requiresImmediateIdAccess) {

	if ( LOG.isTraceEnabled() ) {
		LOG.tracev( "Saving {0}", MessageHelper.infoString( persister, id, source.getFactory() ) );
	}

	final EntityKey key;
	if ( !useIdentityColumn ) {
		key = source.generateEntityKey( id, persister );
		final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
		Object old = persistenceContext.getEntity( key );
		if ( old != null ) {
			if ( persistenceContext.getEntry( old ).getStatus() == Status.DELETED ) {
				source.forceFlush( persistenceContext.getEntry( old ) );
			}
			else {
				return CompletionStages.failedFuture( new NonUniqueObjectException( id, persister.getEntityName() ) );
			}
		}
		persister.setIdentifier( entity, id, source );
	}
	else {
		key = null;
	}

	return reactivePerformSaveOrReplicate(
			entity,
			key,
			persister,
			useIdentityColumn,
			context,
			source,
			requiresImmediateIdAccess
	);
}
 
Example 5
Source File: DefaultDeleteEventListener.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Handle the given delete event.  This is the cascaded form.
 *
 * @param event The delete event.
 * @param transientEntities The cache of entities already deleted
 *
 * @throws HibernateException
 */
public void onDelete(DeleteEvent event, Set transientEntities) throws HibernateException {

	final EventSource source = event.getSession();

	final PersistenceContext persistenceContext = source.getPersistenceContext();
	Object entity = persistenceContext.unproxyAndReassociate( event.getObject() );

	EntityEntry entityEntry = persistenceContext.getEntry( entity );
	final EntityPersister persister;
	final Serializable id;
	final Object version;

	if ( entityEntry == null ) {
		LOG.trace( "Entity was not persistent in delete processing" );

		persister = source.getEntityPersister( event.getEntityName(), entity );

		if ( ForeignKeys.isTransient( persister.getEntityName(), entity, null, source ) ) {
			deleteTransientEntity( source, entity, event.isCascadeDeleteEnabled(), persister, transientEntities );
			// EARLY EXIT!!!
			return;
		}
		performDetachedEntityDeletionCheck( event );

		id = persister.getIdentifier( entity, source );

		if ( id == null ) {
			throw new TransientObjectException(
					"the detached instance passed to delete() had a null identifier"
			);
		}

		final EntityKey key = source.generateEntityKey( id, persister );

		persistenceContext.checkUniqueness( key, entity );

		new OnUpdateVisitor( source, id, entity ).process( entity, persister );

		version = persister.getVersion( entity );

		entityEntry = persistenceContext.addEntity(
				entity,
				(persister.isMutable() ? Status.MANAGED : Status.READ_ONLY),
				persister.getPropertyValues( entity ),
				key,
				version,
				LockMode.NONE,
				true,
				persister,
				false
		);
	}
	else {
		LOG.trace( "Deleting a persistent instance" );

		if ( entityEntry.getStatus() == Status.DELETED || entityEntry.getStatus() == Status.GONE ) {
			LOG.trace( "Object was already deleted" );
			return;
		}
		persister = entityEntry.getPersister();
		id = entityEntry.getId();
		version = entityEntry.getVersion();
	}

	/*if ( !persister.isMutable() ) {
		throw new HibernateException(
				"attempted to delete an object of immutable class: " +
				MessageHelper.infoString(persister)
			);
	}*/

	if ( invokeDeleteLifecycle( source, entity, persister ) ) {
		return;
	}

	deleteEntity(
			source,
			entity,
			entityEntry,
			event.isCascadeDeleteEnabled(),
			event.isOrphanRemovalBeforeUpdates(),
			persister,
			transientEntities
	);

	if ( source.getFactory().getSettings().isIdentifierRollbackEnabled() ) {
		persister.resetIdentifier( entity, id, version, source );
	}
}
 
Example 6
Source File: DefaultDeleteEventListener.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Perform the entity deletion.  Well, as with most operations, does not
 * really perform it; just schedules an action/execution with the
 * {@link org.hibernate.engine.spi.ActionQueue} for execution during flush.
 *
 * @param session The originating session
 * @param entity The entity to delete
 * @param entityEntry The entity's entry in the {@link PersistenceContext}
 * @param isCascadeDeleteEnabled Is delete cascading enabled?
 * @param persister The entity persister.
 * @param transientEntities A cache of already deleted entities.
 */
protected final void deleteEntity(
		final EventSource session,
		final Object entity,
		final EntityEntry entityEntry,
		final boolean isCascadeDeleteEnabled,
		final boolean isOrphanRemovalBeforeUpdates,
		final EntityPersister persister,
		final Set transientEntities) {

	if ( LOG.isTraceEnabled() ) {
		LOG.tracev(
				"Deleting {0}",
				MessageHelper.infoString( persister, entityEntry.getId(), session.getFactory() )
		);
	}

	final PersistenceContext persistenceContext = session.getPersistenceContext();
	final Type[] propTypes = persister.getPropertyTypes();
	final Object version = entityEntry.getVersion();

	final Object[] currentState;
	if ( entityEntry.getLoadedState() == null ) {
		//ie. the entity came in from update()
		currentState = persister.getPropertyValues( entity );
	}
	else {
		currentState = entityEntry.getLoadedState();
	}

	final Object[] deletedState = createDeletedState( persister, currentState, session );
	entityEntry.setDeletedState( deletedState );

	session.getInterceptor().onDelete(
			entity,
			entityEntry.getId(),
			deletedState,
			persister.getPropertyNames(),
			propTypes
	);

	// before any callbacks, etc, so subdeletions see that this deletion happened first
	persistenceContext.setEntryStatus( entityEntry, Status.DELETED );
	final EntityKey key = session.generateEntityKey( entityEntry.getId(), persister );

	cascadeBeforeDelete( session, persister, entity, entityEntry, transientEntities );

	new ForeignKeys.Nullifier( entity, true, false, session )
			.nullifyTransientReferences( entityEntry.getDeletedState(), propTypes );
	new Nullability( session ).checkNullability( entityEntry.getDeletedState(), persister, Nullability.NullabilityCheckType.DELETE );
	persistenceContext.getNullifiableEntityKeys().add( key );

	if ( isOrphanRemovalBeforeUpdates ) {
		// TODO: The removeOrphan concept is a temporary "hack" for HHH-6484.  This should be removed once action/task
		// ordering is improved.
		session.getActionQueue().addAction(
				new OrphanRemovalAction(
						entityEntry.getId(),
						deletedState,
						version,
						entity,
						persister,
						isCascadeDeleteEnabled,
						session
				)
		);
	}
	else {
		// Ensures that containing deletions happen before sub-deletions
		session.getActionQueue().addAction(
				new EntityDeleteAction(
						entityEntry.getId(),
						deletedState,
						version,
						entity,
						persister,
						isCascadeDeleteEnabled,
						session
				)
		);
	}

	cascadeAfterDelete( session, persister, entity, transientEntities );

	// the entry will be removed after the flush, and will no longer
	// override the stale snapshot
	// This is now handled by removeEntity() in EntityDeleteAction
	//persistenceContext.removeDatabaseSnapshot(key);
}
 
Example 7
Source File: DefaultSaveOrUpdateEventListener.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
protected void performUpdate(
		SaveOrUpdateEvent event,
		Object entity,
		EntityPersister persister) throws HibernateException {

	final boolean traceEnabled = LOG.isTraceEnabled();
	if ( traceEnabled && !persister.isMutable() ) {
		LOG.trace( "Immutable instance passed to performUpdate()" );
	}

	if ( traceEnabled ) {
		LOG.tracev(
				"Updating {0}",
				MessageHelper.infoString( persister, event.getRequestedId(), event.getSession().getFactory() )
		);
	}

	final EventSource source = event.getSession();
	final EntityKey key = source.generateEntityKey( event.getRequestedId(), persister );

	source.getPersistenceContext().checkUniqueness( key, entity );

	if ( invokeUpdateLifecycle( entity, persister, source ) ) {
		reassociate( event, event.getObject(), event.getRequestedId(), persister );
		return;
	}

	// this is a transient object with existing persistent state not loaded by the session

	new OnUpdateVisitor( source, event.getRequestedId(), entity ).process( entity, persister );

	// TODO: put this stuff back in to read snapshot from
	// the second-level cache (needs some extra work)
	/*Object[] cachedState = null;

       if ( persister.hasCache() ) {
       	CacheEntry entry = (CacheEntry) persister.getCache()
       			.get( event.getRequestedId(), source.getTimestamp() );
           cachedState = entry==null ?
           		null :
           		entry.getState(); //TODO: half-assemble this stuff
       }*/

	source.getPersistenceContext().addEntity(
			entity,
			( persister.isMutable() ? Status.MANAGED : Status.READ_ONLY ),
			null, // cachedState,
			key,
			persister.getVersion( entity ),
			LockMode.NONE,
			true,
			persister,
			false
	);

	persister.afterReassociate( entity, source );

	if ( traceEnabled ) {
		LOG.tracev(
				"Updating {0}", MessageHelper.infoString(
				persister,
				event.getRequestedId(),
				source.getFactory()
		)
		);
	}

	cascadeOnUpdate( event, persister, entity );
}
 
Example 8
Source File: AbstractReassociateEventListener.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Associates a given entity (either transient or associated with another session) to
 * the given session.
 *
 * @param event The event triggering the re-association
 * @param object The entity to be associated
 * @param id The id of the entity.
 * @param persister The entity's persister instance.
 *
 * @return An EntityEntry representing the entity within this session.
 */
protected final EntityEntry reassociate(AbstractEvent event, Object object, Serializable id, EntityPersister persister) {

	if ( log.isTraceEnabled() ) {
		log.tracev(
				"Reassociating transient instance: {0}",
				MessageHelper.infoString( persister, id, event.getSession().getFactory() )
		);
	}

	final EventSource source = event.getSession();
	final EntityKey key = source.generateEntityKey( id, persister );

	source.getPersistenceContext().checkUniqueness( key, object );

	//get a snapshot
	Object[] values = persister.getPropertyValues( object );
	TypeHelper.deepCopy(
			values,
			persister.getPropertyTypes(),
			persister.getPropertyUpdateability(),
			values,
			source
	);
	Object version = Versioning.getVersion( values, persister );

	EntityEntry newEntry = source.getPersistenceContext().addEntity(
			object,
			( persister.isMutable() ? Status.MANAGED : Status.READ_ONLY ),
			values,
			key,
			version,
			LockMode.NONE,
			true,
			persister,
			false
	);

	new OnLockVisitor( source, id, object ).process( object, persister );

	persister.afterReassociate( object, source );

	return newEntry;

}
 
Example 9
Source File: DefaultMergeEventListener.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Handle the given merge event.
 *
 * @param event The merge event to be handled.
 *
 * @throws HibernateException
 */
public void onMerge(MergeEvent event, Map copiedAlready) throws HibernateException {

	final MergeContext copyCache = (MergeContext) copiedAlready;
	final EventSource source = event.getSession();
	final Object original = event.getOriginal();

	if ( original != null ) {

		final Object entity;
		if ( original instanceof HibernateProxy ) {
			LazyInitializer li = ( (HibernateProxy) original ).getHibernateLazyInitializer();
			if ( li.isUninitialized() ) {
				LOG.trace( "Ignoring uninitialized proxy" );
				event.setResult( source.load( li.getEntityName(), li.getIdentifier() ) );
				return; //EARLY EXIT!
			}
			else {
				entity = li.getImplementation();
			}
		}
		else {
			entity = original;
		}

		if ( copyCache.containsKey( entity ) &&
				( copyCache.isOperatedOn( entity ) ) ) {
			LOG.trace( "Already in merge process" );
			event.setResult( entity );
		}
		else {
			if ( copyCache.containsKey( entity ) ) {
				LOG.trace( "Already in copyCache; setting in merge process" );
				copyCache.setOperatedOn( entity, true );
			}
			event.setEntity( entity );
			EntityState entityState = null;

			// Check the persistence context for an entry relating to this
			// entity to be merged...
			EntityEntry entry = source.getPersistenceContext().getEntry( entity );
			if ( entry == null ) {
				EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
				Serializable id = persister.getIdentifier( entity, source );
				if ( id != null ) {
					final EntityKey key = source.generateEntityKey( id, persister );
					final Object managedEntity = source.getPersistenceContext().getEntity( key );
					entry = source.getPersistenceContext().getEntry( managedEntity );
					if ( entry != null ) {
						// we have specialized case of a detached entity from the
						// perspective of the merge operation.  Specifically, we
						// have an incoming entity instance which has a corresponding
						// entry in the current persistence context, but registered
						// under a different entity instance
						entityState = EntityState.DETACHED;
					}
				}
			}

			if ( entityState == null ) {
				entityState = getEntityState( entity, event.getEntityName(), entry, source );
			}

			switch ( entityState ) {
				case DETACHED:
					entityIsDetached( event, copyCache );
					break;
				case TRANSIENT:
					entityIsTransient( event, copyCache );
					break;
				case PERSISTENT:
					entityIsPersistent( event, copyCache );
					break;
				default: //DELETED
					throw new ObjectDeletedException(
							"deleted instance passed to merge",
							null,
							getLoggableName( event.getEntityName(), entity )
					);
			}
		}

	}

}
 
Example 10
Source File: AbstractSaveEventListener.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Prepares the save call by checking the session caches for a pre-existing
 * entity and performing any lifecycle callbacks.
 *
 * @param entity The entity to be saved.
 * @param id The id by which to save the entity.
 * @param persister The entity's persister instance.
 * @param useIdentityColumn Is an identity column being used?
 * @param anything Generally cascade-specific information.
 * @param source The session from which the event originated.
 * @param requiresImmediateIdAccess does the event context require
 * access to the identifier immediately after execution of this method (if
 * not, post-insert style id generators may be postponed if we are outside
 * a transaction).
 *
 * @return The id used to save the entity; may be null depending on the
 *         type of id generator used and the requiresImmediateIdAccess value
 */
protected Serializable performSave(
		Object entity,
		Serializable id,
		EntityPersister persister,
		boolean useIdentityColumn,
		Object anything,
		EventSource source,
		boolean requiresImmediateIdAccess) {

	if ( LOG.isTraceEnabled() ) {
		LOG.tracev( "Saving {0}", MessageHelper.infoString( persister, id, source.getFactory() ) );
	}

	final EntityKey key;
	if ( !useIdentityColumn ) {
		key = source.generateEntityKey( id, persister );
		Object old = source.getPersistenceContext().getEntity( key );
		if ( old != null ) {
			if ( source.getPersistenceContext().getEntry( old ).getStatus() == Status.DELETED ) {
				source.forceFlush( source.getPersistenceContext().getEntry( old ) );
			}
			else {
				throw new NonUniqueObjectException( id, persister.getEntityName() );
			}
		}
		persister.setIdentifier( entity, id, source );
	}
	else {
		key = null;
	}

	if ( invokeSaveLifecycle( entity, persister, source ) ) {
		return id; //EARLY EXIT
	}

	return performSaveOrReplicate(
			entity,
			key,
			persister,
			useIdentityColumn,
			anything,
			source,
			requiresImmediateIdAccess
	);
}