Java Code Examples for org.hibernate.persister.entity.EntityPersister#getPropertyValues()

The following examples show how to use org.hibernate.persister.entity.EntityPersister#getPropertyValues() . 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: DefaultFlushEntityEventListener.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
private Object[] getValues(Object entity, EntityEntry entry, boolean mightBeDirty, SessionImplementor session) {
	final Object[] loadedState = entry.getLoadedState();
	final Status status = entry.getStatus();
	final EntityPersister persister = entry.getPersister();

	final Object[] values;
	if ( status == Status.DELETED ) {
		//grab its state saved at deletion
		values = entry.getDeletedState();
	}
	else if ( !mightBeDirty && loadedState != null ) {
		values = loadedState;
	}
	else {
		checkId( entity, persister, entry.getId(), session );

		// grab its current state
		values = persister.getPropertyValues( entity );

		checkNaturalId( persister, entry, values, loadedState, session );
	}
	return values;
}
 
Example 2
Source File: StatelessSessionImpl.java    From cacheonix-core with GNU Lesser General Public License v2.1 6 votes vote down vote up
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);
}
 
Example 3
Source File: StatelessSessionImpl.java    From cacheonix-core with GNU Lesser General Public License v2.1 6 votes vote down vote up
public Serializable insert(String entityName, Object entity) {
	errorIfClosed();
	EntityPersister persister = getEntityPersister(entityName, entity);
	Serializable id = persister.getIdentifierGenerator().generate(this, entity);
	Object[] state = persister.getPropertyValues(entity, EntityMode.POJO);
	if ( persister.isVersioned() ) {
		boolean substitute = Versioning.seedVersion(state, persister.getVersionProperty(), persister.getVersionType(), this);
		if ( substitute ) {
			persister.setPropertyValues( entity, state, EntityMode.POJO );
		}
	}
	if ( id == IdentifierGeneratorFactory.POST_INSERT_INDICATOR ) {
		id = persister.insert(state, entity, this);
	}
	else {
		persister.insert(id, state, entity, this);
	}
	persister.setIdentifier(entity, id, EntityMode.POJO);
	return id;
}
 
Example 4
Source File: Cascade.java    From hibernate-reactive with GNU Lesser General Public License v2.1 6 votes vote down vote up
public static CompletionStage<?> fetchLazyAssociationsBeforeCascade(
		CascadingAction<?> action,
		EntityPersister persister,
		Object entity,
		EventSource session) {

	CompletionStage<?> beforeDelete = CompletionStages.nullFuture();
	if ( persister.hasCascades() ) {
		CascadeStyle[] cascadeStyles = persister.getPropertyCascadeStyles();
		Object[] state = persister.getPropertyValues( entity );
		for (int i = 0; i < cascadeStyles.length; i++) {
			if ( cascadeStyles[i].doCascade( action.delegate() ) ) {
				Object fetchable = state[i];
				if ( !Hibernate.isInitialized( fetchable ) ) {
					beforeDelete = beforeDelete.thenCompose( v -> session.unwrap(ReactiveSession.class).reactiveFetch( fetchable, true ) );
				}
			}
		}
	}
	return beforeDelete;
}
 
Example 5
Source File: StatelessSessionImpl.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
@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 );
}
 
Example 6
Source File: StatelessSessionImpl.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
@Override
public Serializable insert(String entityName, Object entity) {
	checkOpen();
	EntityPersister persister = getEntityPersister( entityName, entity );
	Serializable id = persister.getIdentifierGenerator().generate( this, entity );
	Object[] state = persister.getPropertyValues( entity );
	if ( persister.isVersioned() ) {
		boolean substitute = Versioning.seedVersion(
				state,
				persister.getVersionProperty(),
				persister.getVersionType(),
				this
		);
		if ( substitute ) {
			persister.setPropertyValues( entity, state );
		}
	}
	if ( id == IdentifierGeneratorHelper.POST_INSERT_INDICATOR ) {
		id = persister.insert( state, entity, this );
	}
	else {
		persister.insert( id, state, entity, this );
	}
	persister.setIdentifier( entity, id, this );
	return id;
}
 
Example 7
Source File: DefaultReactiveMergeEventListener.java    From hibernate-reactive with GNU Lesser General Public License v2.1 6 votes vote down vote up
private CompletionStage<Void> fetchAndCopyValues(
		final EntityPersister persister,
		final Object entity,
		final Object target,
		final SessionImplementor source,
		final MergeContext mergeContext) {
	CompletionStage<Void> stage = CompletionStages.nullFuture();
	// If entity == target, then nothing needs to be fetched.
	if ( entity != target ) {
		ReactiveSession session = source.unwrap(ReactiveSession.class);
		final Object[] mergeState = persister.getPropertyValues(entity);
		final Object[] managedState = persister.getPropertyValues(target);
		for (int i = 0; i < mergeState.length; i++) {
			Object fetchable = managedState[i];
			// Cascade-merge mappings do not determine what needs to be fetched.
			// The value only needs to be fetched if the incoming value (mergeState[i])
			// is initialized, but its corresponding managed state is not initialized.
			// Initialization must be done before copyValues executes.
			if ( Hibernate.isInitialized( mergeState[i] ) && !Hibernate.isInitialized( managedState[i] ) ) {
				stage = stage.thenCompose( v -> session.reactiveFetch( fetchable, true ) ).thenApply(ignore -> null);
			}
		}
	}
	return stage.thenAccept( v -> copyValues( persister, entity, target, source, mergeContext ) );
}
 
Example 8
Source File: DefaultReactiveFlushEntityEventListener.java    From hibernate-reactive with GNU Lesser General Public License v2.1 6 votes vote down vote up
private Object[] getValues(Object entity, EntityEntry entry, boolean mightBeDirty, SessionImplementor session) {
	final Object[] loadedState = entry.getLoadedState();
	final Status status = entry.getStatus();
	final EntityPersister persister = entry.getPersister();

	final Object[] values;
	if ( status == Status.DELETED ) {
		//grab its state saved at deletion
		values = entry.getDeletedState();
	}
	else if ( !mightBeDirty && loadedState != null ) {
		values = loadedState;
	}
	else {
		checkId( entity, persister, entry.getId(), session );

		// grab its current state
		values = persister.getPropertyValues( entity );

		checkNaturalId( persister, entry, values, loadedState, session );
	}
	return values;
}
 
Example 9
Source File: EntityPrinter.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Renders an entity to a string.
 *
 * @param entityName the entity name
 * @param entity an actual entity object, not a proxy!
 *
 * @return the entity rendered to a string
 */
public String toString(String entityName, Object entity) throws HibernateException {
	EntityPersister entityPersister = factory.getEntityPersister( entityName );

	if ( entityPersister == null || !entityPersister.isInstance( entity ) ) {
		return entity.getClass().getName();
	}

	Map<String, String> result = new HashMap<String, String>();

	if ( entityPersister.hasIdentifierProperty() ) {
		result.put(
				entityPersister.getIdentifierPropertyName(),
				entityPersister.getIdentifierType().toLoggableString(
						entityPersister.getIdentifier( entity ),
						factory
				)
		);
	}

	Type[] types = entityPersister.getPropertyTypes();
	String[] names = entityPersister.getPropertyNames();
	Object[] values = entityPersister.getPropertyValues( entity );
	for ( int i = 0; i < types.length; i++ ) {
		if ( !names[i].startsWith( "_" ) ) {
			String strValue = values[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY ?
					values[i].toString() :
					types[i].toLoggableString( values[i], factory );
			result.put( names[i], strValue );
		}
	}
	return entityName + result.toString();
}
 
Example 10
Source File: Example.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@Override
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) {
	final EntityPersister meta = criteriaQuery.getFactory().getEntityPersister(
			criteriaQuery.getEntityName( criteria )
	);
	final String[] propertyNames = meta.getPropertyNames();
	final Type[] propertyTypes = meta.getPropertyTypes();

	final Object[] values = meta.getPropertyValues( exampleEntity );
	final List<TypedValue> list = new ArrayList<TypedValue>();
	for ( int i=0; i<propertyNames.length; i++ ) {
		final Object value = values[i];
		final Type type = propertyTypes[i];
		final String name = propertyNames[i];

		final boolean isVersionProperty = i == meta.getVersionProperty();

		if ( ! isVersionProperty && isPropertyIncluded( value, name, type ) ) {
			if ( propertyTypes[i].isComponentType() ) {
				addComponentTypedValues( name, value, (CompositeType) type, list, criteria, criteriaQuery );
			}
			else {
				addPropertyTypedValue( value, type, list );
			}
		}
	}

	return list.toArray( new TypedValue[ list.size() ] );
}
 
Example 11
Source File: WrapVisitor.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@Override
void process(Object object, EntityPersister persister) throws HibernateException {
	final Object[] values = persister.getPropertyValues( object );
	final Type[] types = persister.getPropertyTypes();
	processEntityPropertyValues( values, types );
	if ( isSubstitutionRequired() ) {
		persister.setPropertyValues( object, values );
	}
}
 
Example 12
Source File: Example.java    From cacheonix-core with GNU Lesser General Public License v2.1 5 votes vote down vote up
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
	throws HibernateException {

	StringBuffer buf = new StringBuffer().append('(');
	EntityPersister meta = criteriaQuery.getFactory().getEntityPersister( criteriaQuery.getEntityName(criteria) );
	String[] propertyNames = meta.getPropertyNames();
	Type[] propertyTypes = meta.getPropertyTypes();
	//TODO: get all properties, not just the fetched ones!
	Object[] propertyValues = meta.getPropertyValues( entity, getEntityMode(criteria, criteriaQuery) );
	for (int i=0; i<propertyNames.length; i++) {
		Object propertyValue = propertyValues[i];
		String propertyName = propertyNames[i];

		boolean isPropertyIncluded = i!=meta.getVersionProperty() &&
			isPropertyIncluded( propertyValue, propertyName, propertyTypes[i] );
		if (isPropertyIncluded) {
			if ( propertyTypes[i].isComponentType() ) {
				appendComponentCondition(
					propertyName,
					propertyValue,
					(AbstractComponentType) propertyTypes[i],
					criteria,
					criteriaQuery,
					buf
				);
			}
			else {
				appendPropertyCondition(
					propertyName,
					propertyValue,
					criteria,
					criteriaQuery,
					buf
				);
			}
		}
	}
	if ( buf.length()==1 ) buf.append("1=1"); //yuck!
	return buf.append(')').toString();
}
 
Example 13
Source File: Example.java    From cacheonix-core with GNU Lesser General Public License v2.1 5 votes vote down vote up
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
throws HibernateException {

	EntityPersister meta = criteriaQuery.getFactory()
			.getEntityPersister( criteriaQuery.getEntityName(criteria) );
	String[] propertyNames = meta.getPropertyNames();
	Type[] propertyTypes = meta.getPropertyTypes();
	 //TODO: get all properties, not just the fetched ones!
	Object[] values = meta.getPropertyValues( entity, getEntityMode(criteria, criteriaQuery) );
	List list = new ArrayList();
	for (int i=0; i<propertyNames.length; i++) {
		Object value = values[i];
		Type type = propertyTypes[i];
		String name = propertyNames[i];

		boolean isPropertyIncluded = i!=meta.getVersionProperty() &&
			isPropertyIncluded(value, name, type);

		if (isPropertyIncluded) {
			if ( propertyTypes[i].isComponentType() ) {
				addComponentTypedValues(name, value, (AbstractComponentType) type, list, criteria, criteriaQuery);
			}
			else {
				addPropertyTypedValue(value, type, list);
			}
		}
	}
	return (TypedValue[]) list.toArray(TYPED_VALUES);
}
 
Example 14
Source File: WrapVisitor.java    From cacheonix-core with GNU Lesser General Public License v2.1 5 votes vote down vote up
void process(Object object, EntityPersister persister) throws HibernateException {
	EntityMode entityMode = getSession().getEntityMode();
	Object[] values = persister.getPropertyValues( object, entityMode );
	Type[] types = persister.getPropertyTypes();
	processEntityPropertyValues(values, types);
	if ( isSubstitutionRequired() ) {
		persister.setPropertyValues( object, values, entityMode );
	}
}
 
Example 15
Source File: DefaultFlushEntityEventListener.java    From cacheonix-core with GNU Lesser General Public License v2.1 5 votes vote down vote up
private Object[] getValues(
		Object entity,
		EntityEntry entry,
		EntityMode entityMode,
		boolean mightBeDirty,
        SessionImplementor session
) {
	final Object[] loadedState = entry.getLoadedState();
	final Status status = entry.getStatus();
	final EntityPersister persister = entry.getPersister();

	final Object[] values;
	if ( status == Status.DELETED ) {
		//grab its state saved at deletion
		values = entry.getDeletedState();
	}
	else if ( !mightBeDirty && loadedState!=null ) {
		values = loadedState;
	}
	else {
		checkId( entity, persister, entry.getId(), entityMode );

		// grab its current state
		values = persister.getPropertyValues( entity, entityMode );

		checkNaturalId( persister, entry.getId(), values, loadedState, entityMode, session );
	}
	return values;
}
 
Example 16
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 17
Source File: Example.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
@Override
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) {
	final StringBuilder buf = new StringBuilder().append( '(' );
	final EntityPersister meta = criteriaQuery.getFactory().getEntityPersister(
			criteriaQuery.getEntityName( criteria )
	);
	final String[] propertyNames = meta.getPropertyNames();
	final Type[] propertyTypes = meta.getPropertyTypes();

	final Object[] propertyValues = meta.getPropertyValues( exampleEntity );
	for ( int i=0; i<propertyNames.length; i++ ) {
		final Object propertyValue = propertyValues[i];
		final String propertyName = propertyNames[i];

		final boolean isVersionProperty = i == meta.getVersionProperty();
		if ( ! isVersionProperty && isPropertyIncluded( propertyValue, propertyName, propertyTypes[i] ) ) {
			if ( propertyTypes[i].isComponentType() ) {
				appendComponentCondition(
					propertyName,
					propertyValue,
					(CompositeType) propertyTypes[i],
					criteria,
					criteriaQuery,
					buf
				);
			}
			else {
				appendPropertyCondition(
					propertyName,
					propertyValue,
					criteria,
					criteriaQuery,
					buf
				);
			}
		}
	}

	if ( buf.length()==1 ) {
		buf.append( "1=1" );
	}

	return buf.append( ')' ).toString();
}
 
Example 18
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 19
Source File: DefaultDeleteEventListener.java    From cacheonix-core with GNU Lesser General Public License v2.1 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.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 EntityPersister persister,
		final Set transientEntities) {

	if ( log.isTraceEnabled() ) {
		log.trace(
				"deleting " +
						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, session.getEntityMode() );
	}
	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 );
	EntityKey key = new EntityKey( entityEntry.getId(), persister, session.getEntityMode() );

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

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

	// 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 20
Source File: AbstractReassociateEventListener.java    From cacheonix-core with GNU Lesser General Public License v2.1 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.trace(
				"reassociating transient instance: " +
						MessageHelper.infoString( persister, id, event.getSession().getFactory() )
		);
	}

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

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

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

	EntityEntry newEntry = source.getPersistenceContext().addEntity(
			object,
			Status.MANAGED,
			values,
			key,
			version,
			LockMode.NONE,
			true,
			persister,
			false,
			true //will be ignored, using the existing Entry instead
	);

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

	persister.afterReassociate( object, source );

	return newEntry;

}