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

The following examples show how to use org.hibernate.event.EventSource#getEntityPersister() . 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: DefaultPersistEventListener.java    From cacheonix-core with GNU Lesser General Public License v2.1 6 votes vote down vote up
protected void entityIsPersistent(PersistEvent event, Map createCache) {
	log.trace("ignoring persistent instance");
	final EventSource source = event.getSession();
	
	//TODO: check that entry.getIdentifier().equals(requestedId)
	
	final Object entity = source.getPersistenceContext().unproxy( event.getObject() );
	final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
	
	if ( createCache.put(entity, entity)==null ) {
		//TODO: merge into one method!
		cascadeBeforeSave(source, persister, entity, createCache);
		cascadeAfterSave(source, persister, entity, createCache);
	}

}
 
Example 2
Source File: AbstractSaveEventListener.java    From cacheonix-core with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Prepares the save call using a newly generated id.
 *
 * @param entity The entity to be saved
 * @param entityName The entity-name for the entity to be saved
 * @param anything Generally cascade-specific information.
 * @param source The session which is the source of this save event.
 * @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 saveWithGeneratedId(
		Object entity,
		String entityName,
		Object anything,
		EventSource source,
		boolean requiresImmediateIdAccess) {
	EntityPersister persister = source.getEntityPersister( entityName, entity );
	Serializable generatedId = persister.getIdentifierGenerator().generate( source, entity );
	if ( generatedId == null ) {
		throw new IdentifierGenerationException( "null id generated for:" + entity.getClass() );
	}
	else if ( generatedId == IdentifierGeneratorFactory.SHORT_CIRCUIT_INDICATOR ) {
		return source.getIdentifier( entity );
	}
	else if ( generatedId == IdentifierGeneratorFactory.POST_INSERT_INDICATOR ) {
		return performSave( entity, null, persister, true, anything, source, requiresImmediateIdAccess );
	}
	else {

		if ( log.isDebugEnabled() ) {
			log.debug(
					"generated identifier: " +
							persister.getIdentifierType().toLoggableString( generatedId, source.getFactory() ) +
							", using strategy: " +
							persister.getIdentifierGenerator().getClass().getName()
					//TODO: define toString()s for generators
			);
		}

		return performSave( entity, generatedId, persister, false, anything, source, true );
	}
}
 
Example 3
Source File: DefaultDeleteEventListener.java    From cacheonix-core with GNU Lesser General Public License v2.1 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;
		}
		else {
			performDetachedEntityDeletionCheck( event );
		}

		id = persister.getIdentifier( entity, source.getEntityMode() );

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

		EntityKey key = new EntityKey( id, persister, source.getEntityMode() );

		persistenceContext.checkUniqueness( key, entity );

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

		version = persister.getVersion( entity, source.getEntityMode() );

		entityEntry = persistenceContext.addEntity(
				entity,
				Status.MANAGED,
				persister.getPropertyValues( entity, source.getEntityMode() ),
				key,
				version,
				LockMode.NONE,
				true,
				persister,
				false,
				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(), persister, transientEntities );

	if ( source.getFactory().getSettings().isIdentifierRollbackEnabled() ) {
		persister.resetIdentifier( entity, id, version, source.getEntityMode() );
	}
}
 
Example 4
Source File: DefaultReplicateEventListener.java    From cacheonix-core with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * Handle the given replicate event.
 *
 * @param event The replicate event to be handled.
 *
 * @throws TransientObjectException An invalid attempt to replicate a transient entity.
 */
public void onReplicate(ReplicateEvent event) {
	final EventSource source = event.getSession();
	if ( source.getPersistenceContext().reassociateIfUninitializedProxy( event.getObject() ) ) {
		log.trace( "uninitialized proxy passed to replicate()" );
		return;
	}

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

	if ( source.getPersistenceContext().isEntryFor( entity ) ) {
		log.trace( "ignoring persistent instance passed to replicate()" );
		//hum ... should we cascade anyway? throw an exception? fine like it is?
		return;
	}

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

	// get the id from the object
	/*if ( persister.isUnsaved(entity, source) ) {
		throw new TransientObjectException("transient instance passed to replicate()");
	}*/
	Serializable id = persister.getIdentifier( entity, source.getEntityMode() );
	if ( id == null ) {
		throw new TransientObjectException( "instance with null id passed to replicate()" );
	}

	final ReplicationMode replicationMode = event.getReplicationMode();

	final Object oldVersion;
	if ( replicationMode == ReplicationMode.EXCEPTION ) {
		//always do an INSERT, and let it fail by constraint violation
		oldVersion = null;
	}
	else {
		//what is the version on the database?
		oldVersion = persister.getCurrentVersion( id, source );			
	}

	if ( oldVersion != null ) { 			
		if ( log.isTraceEnabled() ) {
			log.trace(
					"found existing row for " +
							MessageHelper.infoString( persister, id, source.getFactory() )
			);
		}

		/// HHH-2378
		final Object realOldVersion = persister.isVersioned() ? oldVersion : null;
		
		boolean canReplicate = replicationMode.shouldOverwriteCurrentVersion(
				entity,
				realOldVersion,
				persister.getVersion( entity, source.getEntityMode() ),
				persister.getVersionType()
		);

		if ( canReplicate ) {
			//will result in a SQL UPDATE:
			performReplication( entity, id, realOldVersion, persister, replicationMode, source );
		}
		else {
			//else do nothing (don't even reassociate object!)
			log.trace( "no need to replicate" );
		}

		//TODO: would it be better to do a refresh from db?
	}
	else {
		// no existing row - do an insert
		if ( log.isTraceEnabled() ) {
			log.trace(
					"no existing row, replicating new instance " +
							MessageHelper.infoString( persister, id, source.getFactory() )
			);
		}

		final boolean regenerate = persister.isIdentifierAssignedByInsert(); // prefer re-generation of identity!
		final EntityKey key = regenerate ?
				null : new EntityKey( id, persister, source.getEntityMode() );

		performSaveOrReplicate(
				entity,
				key,
				persister,
				regenerate,
				replicationMode,
				source,
				true
		);

	}
}
 
Example 5
Source File: DefaultMergeEventListener.java    From cacheonix-core with GNU Lesser General Public License v2.1 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 copyCache) throws HibernateException {

	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) ) {
			log.trace("already merged");
			event.setResult(entity);
		}
		else {
			event.setEntity( entity );
			int entityState = -1;

			// 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.getEntityMode() );
				if ( id != null ) {
					EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
					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 = DETACHED;
					}
				}
			}

			if ( entityState == -1 ) {
				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 6
Source File: DefaultMergeEventListener.java    From cacheonix-core with GNU Lesser General Public License v2.1 4 votes vote down vote up
protected void entityIsPersistent(MergeEvent event, Map copyCache) {
	log.trace("ignoring persistent instance");
	
	//TODO: check that entry.getIdentifier().equals(requestedId)
	
	final Object entity = event.getEntity();
	final EventSource source = event.getSession();
	final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
	
	copyCache.put(entity, entity); //before cascade!
	
	cascadeOnMerge(source, persister, entity, copyCache);
	copyValues(persister, entity, entity, source, copyCache);
	
	event.setResult(entity);
}
 
Example 7
Source File: DefaultMergeEventListener.java    From cacheonix-core with GNU Lesser General Public License v2.1 4 votes vote down vote up
protected void entityIsTransient(MergeEvent event, Map copyCache) {
	
	log.trace("merging transient instance");
	
	final Object entity = event.getEntity();
	final EventSource source = event.getSession();

	final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
	final String entityName = persister.getEntityName();
	
	final Serializable id = persister.hasIdentifierProperty() ?
			persister.getIdentifier( entity, source.getEntityMode() ) :
	        null;
	
	final Object copy = persister.instantiate( id, source.getEntityMode() );  //TODO: should this be Session.instantiate(Persister, ...)?
	copyCache.put(entity, copy); //before cascade!
	
	// cascade first, so that all unsaved objects get their
	// copy created before we actually copy
	//cascadeOnMerge(event, persister, entity, copyCache, Cascades.CASCADE_BEFORE_MERGE);
	super.cascadeBeforeSave(source, persister, entity, copyCache);
	copyValues(persister, entity, copy, source, copyCache, ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT);
	
	//this bit is only *really* absolutely necessary for handling 
	//requestedId, but is also good if we merge multiple object 
	//graphs, since it helps ensure uniqueness
	final Serializable requestedId = event.getRequestedId();
	if (requestedId==null) {
		saveWithGeneratedId( copy, entityName, copyCache, source, false );
	}
	else {
		saveWithRequestedId( copy, requestedId, entityName, copyCache, source );
	}
	
	// cascade first, so that all unsaved objects get their 
	// copy created before we actually copy
	super.cascadeAfterSave(source, persister, entity, copyCache);
	copyValues(persister, entity, copy, source, copyCache, ForeignKeyDirection.FOREIGN_KEY_TO_PARENT);
	
	event.setResult(copy);

}
 
Example 8
Source File: DefaultMergeEventListener.java    From cacheonix-core with GNU Lesser General Public License v2.1 4 votes vote down vote up
protected void entityIsDetached(MergeEvent event, Map copyCache) {
	
	log.trace("merging detached instance");
	
	final Object entity = event.getEntity();
	final EventSource source = event.getSession();

	final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
	final String entityName = persister.getEntityName();
		
	Serializable id = event.getRequestedId();
	if ( id == null ) {
		id = persister.getIdentifier( entity, source.getEntityMode() );
	}
	else {
		// check that entity id = requestedId
		Serializable entityId = persister.getIdentifier( entity, source.getEntityMode() );
		if ( !persister.getIdentifierType().isEqual( id, entityId, source.getEntityMode(), source.getFactory() ) ) {
			throw new HibernateException( "merge requested with id not matching id of passed entity" );
		}
	}
	
	String previousFetchProfile = source.getFetchProfile();
	source.setFetchProfile("merge");
	//we must clone embedded composite identifiers, or 
	//we will get back the same instance that we pass in
	final Serializable clonedIdentifier = (Serializable) persister.getIdentifierType()
			.deepCopy( id, source.getEntityMode(), source.getFactory() );
	final Object result = source.get(entityName, clonedIdentifier);
	source.setFetchProfile(previousFetchProfile);
	
	if ( result == null ) {
		//TODO: we should throw an exception if we really *know* for sure  
		//      that this is a detached instance, rather than just assuming
		//throw new StaleObjectStateException(entityName, id);
		
		// we got here because we assumed that an instance
		// with an assigned id was detached, when it was
		// really persistent
		entityIsTransient(event, copyCache);
	}
	else {
		copyCache.put(entity, result); //before cascade!

		final Object target = source.getPersistenceContext().unproxy(result);
		if ( target == entity ) {
			throw new AssertionFailure("entity was not detached");
		}
		else if ( !source.getEntityName(target).equals(entityName) ) {
			throw new WrongClassException(
					"class of the given object did not match class of persistent copy",
					event.getRequestedId(),
					entityName
				);
		}
		else if ( isVersionChanged( entity, source, persister, target ) ) {
			if ( source.getFactory().getStatistics().isStatisticsEnabled() ) {
				source.getFactory().getStatisticsImplementor()
						.optimisticFailure( entityName );
			}
			throw new StaleObjectStateException( entityName, id );
		}

		// cascade first, so that all unsaved objects get their 
		// copy created before we actually copy
		cascadeOnMerge(source, persister, entity, copyCache);
		copyValues(persister, entity, target, source, copyCache);
		
		//copyValues works by reflection, so explicitly mark the entity instance dirty
		markInterceptorDirty( entity, target );
		
		event.setResult(result);
	}

}