org.hibernate.persister.entity.EntityPersister#getIdentifier ( )源码实例Demo

下面列出了org.hibernate.persister.entity.EntityPersister#getIdentifier ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: cacheonix-core   文件: StatelessSessionImpl.java
public void update(String entityName, Object entity) {
	errorIfClosed();
	EntityPersister persister = getEntityPersister(entityName, entity);
	Serializable id = persister.getIdentifier(entity, EntityMode.POJO);
	Object[] state = persister.getPropertyValues(entity, EntityMode.POJO);
	Object oldVersion;
	if ( persister.isVersioned() ) {
		oldVersion = persister.getVersion(entity, EntityMode.POJO);
		Object newVersion = Versioning.increment( oldVersion, persister.getVersionType(), this );
		Versioning.setVersion(state, newVersion, persister);
		persister.setPropertyValues(entity, state, EntityMode.POJO);
	}
	else {
		oldVersion = null;
	}
	persister.update(id, state, null, false, null, oldVersion, entity, null, this);
}
 
源代码2 项目: lams   文件: StatelessSessionImpl.java
@Override
public void update(String entityName, Object entity) {
	checkOpen();
	EntityPersister persister = getEntityPersister( entityName, entity );
	Serializable id = persister.getIdentifier( entity, this );
	Object[] state = persister.getPropertyValues( entity );
	Object oldVersion;
	if ( persister.isVersioned() ) {
		oldVersion = persister.getVersion( entity );
		Object newVersion = Versioning.increment( oldVersion, persister.getVersionType(), this );
		Versioning.setVersion( state, newVersion, persister );
		persister.setPropertyValues( entity, state );
	}
	else {
		oldVersion = null;
	}
	persister.update( id, state, null, false, null, oldVersion, entity, null, this );
}
 
源代码3 项目: lams   文件: DefaultSaveOrUpdateEventListener.java
/**
 * Determine the id to use for updating.
 *
 * @param entity The entity.
 * @param persister The entity persister
 * @param requestedId The requested identifier
 * @param session The session
 *
 * @return The id.
 *
 * @throws TransientObjectException If the entity is considered transient.
 */
protected Serializable getUpdateId(
		Object entity,
		EntityPersister persister,
		Serializable requestedId,
		SessionImplementor session) {
	// use the id assigned to the instance
	Serializable id = persister.getIdentifier( entity, session );
	if ( id == null ) {
		// assume this is a newly instantiated transient object
		// which should be saved rather than updated
		throw new TransientObjectException(
				"The given object has a null identifier: " +
						persister.getEntityName()
		);
	}
	else {
		return id;
	}

}
 
源代码4 项目: hibernate-reactive   文件: ForeignKeys.java
/**
 * Is this instance, which we know is not persistent, actually transient?
 * <p/>
 * If <tt>assumed</tt> is non-null, don't hit the database to make the determination, instead assume that
 * value; the client code must be prepared to "recover" in the case that this assumed result is incorrect.
 *
 * @param entityName The name of the entity
 * @param entity The entity instance
 * @param assumed The assumed return value, if avoiding database hit is desired
 * @param session The session
 *
 * @return {@code true} if the given entity is transient (unsaved)
 */
public static CompletionStage<Boolean> isTransient(String entityName, Object entity, Boolean assumed,
												   SessionImplementor session) {
	if ( entity == LazyPropertyInitializer.UNFETCHED_PROPERTY ) {
		// an unfetched association can only point to
		// an entity that already exists in the db
		return CompletionStages.falseFuture();
	}

	// let the interceptor inspect the instance to decide
	Boolean isUnsaved = session.getInterceptor().isTransient( entity );
	if ( isUnsaved != null ) {
		return CompletionStages.completedFuture( isUnsaved );
	}

	// let the persister inspect the instance to decide
	final EntityPersister persister = session.getEntityPersister( entityName, entity );
	isUnsaved = persister.isTransient( entity, session );
	if ( isUnsaved != null ) {
		return CompletionStages.completedFuture( isUnsaved );
	}

	// we use the assumed value, if there is one, to avoid hitting
	// the database
	if ( assumed != null ) {
		return CompletionStages.completedFuture( assumed );
	}

	// hit the database, after checking the session cache for a snapshot
	ReactivePersistenceContextAdapter persistenceContext =
			(ReactivePersistenceContextAdapter) session.getPersistenceContextInternal();
	Serializable id = persister.getIdentifier(entity, session);
	return persistenceContext.reactiveGetDatabaseSnapshot( id, persister).thenApply(Objects::isNull);
}
 
private void disallowDeletionOfDetached(DeleteEvent event) {
	EventSource source = event.getSession();
	String entityName = event.getEntityName();
	EntityPersister persister = source.getEntityPersister( entityName, event.getObject() );
	Serializable id = persister.getIdentifier( event.getObject(), source );
	entityName = entityName == null ? source.guessEntityName( event.getObject() ) : entityName;
	throw new IllegalArgumentException( "Removing a detached instance " + entityName + "#" + id );
}
 
源代码6 项目: lams   文件: DefaultMergeEventListener.java
protected void entityIsTransient(MergeEvent event, Map copyCache) {

		LOG.trace( "Merging transient instance" );

		final Object entity = event.getEntity();
		final EventSource source = event.getSession();

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

		final Serializable id = persister.hasIdentifierProperty() ?
				persister.getIdentifier( entity, source ) :
				null;
		if ( copyCache.containsKey( entity ) ) {
			persister.setIdentifier( copyCache.get( entity ), id, source );
		}
		else {
			( (MergeContext) copyCache ).put( entity, source.instantiate( persister, id ), true ); //before cascade!
		}
		final Object copy = copyCache.get( entity );

		// 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.FROM_PARENT );

		saveTransientEntity( copy, entityName, event.getRequestedId(), source, copyCache );

		// 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.TO_PARENT );

		event.setResult( copy );
	}
 
private boolean existsInDatabase(Object entity, EventSource source, EntityPersister persister) {
	final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
	EntityEntry entry = persistenceContext.getEntry( entity );
	if ( entry == null ) {
		Serializable id = persister.getIdentifier( entity, source );
		if ( id != null ) {
			final EntityKey key = source.generateEntityKey( id, persister );
			final Object managedEntity = persistenceContext.getEntity( key );
			entry = persistenceContext.getEntry( managedEntity );
		}
	}

	return entry != null && entry.isExistsInDatabase();
}
 
源代码8 项目: lams   文件: IdTransferringMergeEventListener.java
/**
 * Hibernate 3.1 implementation of ID transferral.
 */
@Override
protected void entityIsTransient(MergeEvent event, Map copyCache) {
	super.entityIsTransient(event, copyCache);
	SessionImplementor session = event.getSession();
	EntityPersister persister = session.getEntityPersister(event.getEntityName(), event.getEntity());
	// Extract id from merged copy (which is currently registered with Session).
	Serializable id = persister.getIdentifier(event.getResult(), session.getEntityMode());
	// Set id on original object (which remains detached).
	persister.setIdentifier(event.getOriginal(), id, session.getEntityMode());
}
 
/**
 * Hibernate 3.1 implementation of ID transferral.
 */
@Override
protected void entityIsTransient(MergeEvent event, Map copyCache) {
	super.entityIsTransient(event, copyCache);
	SessionImplementor session = event.getSession();
	EntityPersister persister = session.getEntityPersister(event.getEntityName(), event.getEntity());
	// Extract id from merged copy (which is currently registered with Session).
	Serializable id = persister.getIdentifier(event.getResult(), session.getEntityMode());
	// Set id on original object (which remains detached).
	persister.setIdentifier(event.getOriginal(), id, session.getEntityMode());
}
 
源代码10 项目: cacheonix-core   文件: EntityType.java
/**
 * {@inheritDoc}
 */
public boolean isEqual(Object x, Object y, EntityMode entityMode, SessionFactoryImplementor factory) {
	EntityPersister persister = factory.getEntityPersister(associatedEntityName);
	if ( !persister.canExtractIdOutOfEntity() ) {
		return super.isEqual(x, y, entityMode);
	}

	Serializable xid;
	if (x instanceof HibernateProxy) {
		xid = ( (HibernateProxy) x ).getHibernateLazyInitializer()
				.getIdentifier();
	}
	else {
		xid = persister.getIdentifier(x, entityMode);
	}

	Serializable yid;
	if (y instanceof HibernateProxy) {
		yid = ( (HibernateProxy) y ).getHibernateLazyInitializer()
				.getIdentifier();
	}
	else {
		yid = persister.getIdentifier(y, entityMode);
	}

	return persister.getIdentifierType()
			.isEqual(xid, yid, entityMode, factory);
}
 
源代码11 项目: lams   文件: StatelessSessionImpl.java
@Override
public void delete(String entityName, Object entity) {
	checkOpen();
	EntityPersister persister = getEntityPersister( entityName, entity );
	Serializable id = persister.getIdentifier( entity, this );
	Object version = persister.getVersion( entity );
	persister.delete( id, version, entity, this );
}
 
源代码12 项目: cacheonix-core   文件: EntityType.java
/**
 * Get the identifier value of an instance or proxy.
 * <p/>
 * Intended only for loggin purposes!!!
 *
 * @param object The object from which to extract the identifier.
 * @param persister The entity persister
 * @param entityMode The entity mode
 * @return The extracted identifier.
 */
private static Serializable getIdentifier(Object object, EntityPersister persister, EntityMode entityMode) {
	if (object instanceof HibernateProxy) {
		HibernateProxy proxy = (HibernateProxy) object;
		LazyInitializer li = proxy.getHibernateLazyInitializer();
		return li.getIdentifier();
	}
	else {
		return persister.getIdentifier( object, entityMode );
	}
}
 
源代码13 项目: lams   文件: EntityType.java
/**
 * Generate a loggable representation of an instance of the value mapped by this type.
 *
 * @param value The instance to be logged.
 * @param factory The session factory.
 *
 * @return The loggable string.
 *
 * @throws HibernateException Generally some form of resolution problem.
 */
@Override
public String toLoggableString(Object value, SessionFactoryImplementor factory) {
	if ( value == null ) {
		return "null";
	}

	final EntityPersister persister = getAssociatedEntityPersister( factory );
	if ( !persister.getEntityTuplizer().isInstance( value ) ) {
		// it should be the id type...
		if ( persister.getIdentifierType().getReturnedClass().isInstance( value ) ) {
			return associatedEntityName + "#" + value;
		}
	}

	final StringBuilder result = new StringBuilder().append( associatedEntityName );

	if ( persister.hasIdentifierProperty() ) {
		final Serializable id;
		if ( value instanceof HibernateProxy ) {
			HibernateProxy proxy = (HibernateProxy) value;
			id = proxy.getHibernateLazyInitializer().getIdentifier();
		}
		else {
			id = persister.getIdentifier( value );
		}

		result.append( '#' )
				.append( persister.getIdentifierType().toLoggableString( id, factory ) );
	}

	return result.toString();
}
 
源代码14 项目: cacheonix-core   文件: DefaultMergeEventListener.java
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);
	}

}
 
@Override
public CompletionStage<Void> reactiveOnLock(LockEvent event) throws HibernateException {
	if ( event.getObject() == null ) {
		throw new NullPointerException( "attempted to lock null" );
	}

	if ( event.getLockMode() == LockMode.WRITE ) {
		throw new HibernateException( "Invalid lock mode for lock()" );
	}

	if ( event.getLockMode() == LockMode.UPGRADE_SKIPLOCKED ) {
		log.explicitSkipLockedLockCombo();
	}

	SessionImplementor source = event.getSession();
	final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
	Object entity = persistenceContext.unproxyAndReassociate( event.getObject() );
	//TODO: if object was an uninitialized proxy, this is inefficient,
	//      resulting in two SQL selects

	EntityEntry entry = persistenceContext.getEntry(entity);
	CompletionStage<EntityEntry> stage;
	if (entry==null) {
		final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
		final Serializable id = persister.getIdentifier( entity, source );
		stage = ForeignKeys.isNotTransient( event.getEntityName(), entity, Boolean.FALSE, source )
				.thenApply(
						trans -> {
							if (!trans) {
								throw new TransientObjectException(
										"cannot lock an unsaved transient instance: " +
												persister.getEntityName()
								);
							}

							EntityEntry e = reassociate(event, entity, id, persister);
							cascadeOnLock(event, persister, entity);
							return e;
						} );

	}
	else {
		stage = CompletionStages.completedFuture(entry);
	}

	return stage.thenCompose( e -> upgradeLock( entity, e, event.getLockOptions(), event.getSession() ) );
}
 
protected CompletionStage<Void> entityIsTransient(MergeEvent event, MergeContext copyCache) {

		LOG.trace( "Merging transient instance" );

		final Object entity = event.getEntity();
		final EventSource session = event.getSession();

		final String entityName = event.getEntityName();
		final EntityPersister persister = session.getEntityPersister( entityName, entity );

		final Serializable id = persister.hasIdentifierProperty()
				? persister.getIdentifier( entity, session )
				: null;

		final Object copy;
		final Object existingCopy = copyCache.get( entity );
		if ( existingCopy != null ) {
			persister.setIdentifier( copyCache.get( entity ), id, session );
			copy = existingCopy;
		}
		else {
			copy = session.instantiate( persister, id );

			//before cascade!
			copyCache.put( entity, copy, true );
		}

		// cascade first, so that all unsaved objects get their
		// copy created before we actually copy
		//cascadeOnMerge(event, persister, entity, copyCache, Cascades.CASCADE_BEFORE_MERGE);
		return super.cascadeBeforeSave( session, persister, entity, copyCache )
				.thenAccept( v -> copyValues( persister, entity, copy, session, copyCache, ForeignKeyDirection.FROM_PARENT ) )
				.thenCompose( v -> saveTransientEntity( copy, entityName, event.getRequestedId(), session, copyCache ) )
				.thenCompose( v -> super.cascadeAfterSave( session, persister, entity, copyCache ) )
				.thenAccept( v -> {
					copyValues(persister, entity, copy, session, copyCache, ForeignKeyDirection.TO_PARENT);

					event.setResult(copy);

					if (copy instanceof PersistentAttributeInterceptable) {
						final PersistentAttributeInterceptable interceptable = (PersistentAttributeInterceptable) copy;
						final PersistentAttributeInterceptor interceptor = interceptable.$$_hibernate_getInterceptor();
						if (interceptor == null) {
							persister.getBytecodeEnhancementMetadata().injectInterceptor(copy, id, session);
						}
					}
				});
	}
 
protected CompletionStage<Void> entityIsDetached(MergeEvent event, MergeContext 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 requestedId = event.getRequestedId();
		Serializable id;
		if ( requestedId == null ) {
			id = persister.getIdentifier( entity, source );
		}
		else {
			id = requestedId;
			// check that entity id = requestedId
			Serializable entityId = persister.getIdentifier( entity, source );
			if ( !persister.getIdentifierType().isEqual( id, entityId, source.getFactory() ) ) {
				throw new HibernateException( "merge requested with id not matching id of passed entity" );
			}
		}

		String previousFetchProfile = source.getLoadQueryInfluencers().getInternalFetchProfile();
		source.getLoadQueryInfluencers().setInternalFetchProfile( "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.getFactory() );

		return source.unwrap(ReactiveSession.class)
				.reactiveGet( (Class<?>) persister.getMappedClass(), clonedIdentifier )
				.thenCompose(result -> {
					if ( result!=null ) {
						// before cascade!
						copyCache.put(entity, result, true);

						Object target = unproxyManagedForDetachedMerging(entity, result, persister, source);
						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) ) {
							final StatisticsImplementor statistics = source.getFactory().getStatistics();
							if (statistics.isStatisticsEnabled()) {
								statistics.optimisticFailure(entityName);
							}
							throw new StaleObjectStateException(entityName, id);
						}

						// cascade first, so that all unsaved objects get their
						// copy created before we actually copy
						return cascadeOnMerge( source, persister, entity, copyCache )
								.thenCompose( v -> fetchAndCopyValues( persister, entity, target, source, copyCache ) )
								.thenAccept(v -> {
									// copyValues() (called by fetchAndCopyValues) works by reflection,
									// so explicitly mark the entity instance dirty
									markInterceptorDirty(entity, target, persister);
									event.setResult(result);
								});
					}
					else {
						//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
						return entityIsTransient(event, copyCache);
					}
				})
				.whenComplete( (v,e) -> source.getLoadQueryInfluencers().setInternalFetchProfile(previousFetchProfile) );

	}
 
源代码18 项目: lams   文件: DefaultMergeEventListener.java
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 );
		}
		else {
			// check that entity id = requestedId
			Serializable entityId = persister.getIdentifier( entity, source );
			if ( !persister.getIdentifierType().isEqual( id, entityId, source.getFactory() ) ) {
				throw new HibernateException( "merge requested with id not matching id of passed entity" );
			}
		}

		String previousFetchProfile = source.getLoadQueryInfluencers().getInternalFetchProfile();
		source.getLoadQueryInfluencers().setInternalFetchProfile( "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.getFactory() );
		final Object result = source.get( entityName, clonedIdentifier );
		source.getLoadQueryInfluencers().setInternalFetchProfile( 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 {
			( (MergeContext) copyCache ).put( entity, result, true ); //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().getStatistics().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, persister );

			event.setResult( result );
		}

	}
 
源代码19 项目: lams   文件: DefaultMergeEventListener.java
/**
 * 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 )
					);
			}
		}

	}

}
 
源代码20 项目: lams   文件: DefaultPersistEventListener.java
/**
 * Handle the given create event.
 *
 * @param event The create event to be handled.
 *
 */
public void onPersist(PersistEvent event, Map createCache) throws HibernateException {
	final SessionImplementor source = event.getSession();
	final Object object = event.getObject();

	final Object entity;
	if ( object instanceof HibernateProxy ) {
		LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
		if ( li.isUninitialized() ) {
			if ( li.getSession() == source ) {
				return; //NOTE EARLY EXIT!
			}
			else {
				throw new PersistentObjectException( "uninitialized proxy passed to persist()" );
			}
		}
		entity = li.getImplementation();
	}
	else {
		entity = object;
	}

	final String entityName;
	if ( event.getEntityName() != null ) {
		entityName = event.getEntityName();
	}
	else {
		entityName = source.bestGuessEntityName( entity );
		event.setEntityName( entityName );
	}

	final EntityEntry entityEntry = source.getPersistenceContext().getEntry( entity );
	EntityState entityState = getEntityState( entity, entityName, entityEntry, source );
	if ( entityState == EntityState.DETACHED ) {
		// JPA 2, in its version of a "foreign generated", allows the id attribute value
		// to be manually set by the user, even though this manual value is irrelevant.
		// The issue is that this causes problems with the Hibernate unsaved-value strategy
		// which comes into play here in determining detached/transient state.
		//
		// Detect if we have this situation and if so null out the id value and calculate the
		// entity state again.

		// NOTE: entityEntry must be null to get here, so we cannot use any of its values
		EntityPersister persister = source.getFactory().getEntityPersister( entityName );
		if ( ForeignGenerator.class.isInstance( persister.getIdentifierGenerator() ) ) {
			if ( LOG.isDebugEnabled() && persister.getIdentifier( entity, source ) != null ) {
				LOG.debug( "Resetting entity id attribute to null for foreign generator" );
			}
			persister.setIdentifier( entity, null, source );
			entityState = getEntityState( entity, entityName, entityEntry, source );
		}
	}

	switch ( entityState ) {
		case DETACHED: {
			throw new PersistentObjectException(
					"detached entity passed to persist: " +
							getLoggableName( event.getEntityName(), entity )
			);
		}
		case PERSISTENT: {
			entityIsPersistent( event, createCache );
			break;
		}
		case TRANSIENT: {
			entityIsTransient( event, createCache );
			break;
		}
		case DELETED: {
			entityEntry.setStatus( Status.MANAGED );
			entityEntry.setDeletedState( null );
			event.getSession().getActionQueue().unScheduleDeletion( entityEntry, event.getObject() );
			entityIsDeleted( event, createCache );
			break;
		}
		default: {
			throw new ObjectDeletedException(
					"deleted entity passed to persist",
					null,
					getLoggableName( event.getEntityName(), entity )
			);
		}
	}

}