HHH-4704 - Pass session into EntityTuplizer#setIdentifier

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18733 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Steve Ebersole 2010-02-08 19:27:00 +00:00
parent 7373796908
commit 839e23458a
23 changed files with 168 additions and 74 deletions

View File

@ -251,8 +251,7 @@ public final class Cascade {
if ( loadedValue != null ) { if ( loadedValue != null ) {
final String entityName = entry.getPersister().getEntityName(); final String entityName = entry.getPersister().getEntityName();
if ( log.isTraceEnabled() ) { if ( log.isTraceEnabled() ) {
final Serializable id = entry.getPersister() final Serializable id = entry.getPersister().getIdentifier( loadedValue, eventSource );
.getIdentifier( loadedValue, eventSource.getEntityMode() );
final String description = MessageHelper.infoString( entityName, id ); final String description = MessageHelper.infoString( entityName, id );
log.trace( "deleting orphaned entity instance: " + description ); log.trace( "deleting orphaned entity instance: " + description );
} }

View File

@ -85,8 +85,7 @@ public final class Collections {
boolean hasOrphanDelete = loadedPersister != null && boolean hasOrphanDelete = loadedPersister != null &&
loadedPersister.hasOrphanDelete(); loadedPersister.hasOrphanDelete();
if (hasOrphanDelete) { if (hasOrphanDelete) {
Serializable ownerId = loadedPersister.getOwnerEntityPersister() Serializable ownerId = loadedPersister.getOwnerEntityPersister().getIdentifier( coll.getOwner(), session );
.getIdentifier( coll.getOwner(), session.getEntityMode() );
if ( ownerId == null ) { if ( ownerId == null ) {
// the owning entity may have been deleted and its identifier unset due to // the owning entity may have been deleted and its identifier unset due to
// identifier-rollback; in which case, try to look up its identifier from // identifier-rollback; in which case, try to look up its identifier from

View File

@ -209,8 +209,10 @@ public final class ForeignKeys {
if (assumed!=null) return assumed.booleanValue(); if (assumed!=null) return assumed.booleanValue();
// hit the database, after checking the session cache for a snapshot // hit the database, after checking the session cache for a snapshot
Object[] snapshot = session.getPersistenceContext() Object[] snapshot = session.getPersistenceContext().getDatabaseSnapshot(
.getDatabaseSnapshot( persister.getIdentifier( entity, session.getEntityMode() ), persister ); persister.getIdentifier( entity, session ),
persister
);
return snapshot==null; return snapshot==null;
} }
@ -244,7 +246,7 @@ public final class ForeignKeys {
(entityName == null ? session.guessEntityName( object ) : entityName) (entityName == null ? session.guessEntityName( object ) : entityName)
); );
} }
id = session.getEntityPersister( entityName, object ).getIdentifier( object, session.getEntityMode() ); id = session.getEntityPersister( entityName, object ).getIdentifier( object, session );
} }
return id; return id;
} }

View File

@ -108,7 +108,7 @@ public class DefaultDeleteEventListener implements DeleteEventListener {
performDetachedEntityDeletionCheck( event ); performDetachedEntityDeletionCheck( event );
} }
id = persister.getIdentifier( entity, source.getEntityMode() ); id = persister.getIdentifier( entity, source );
if ( id == null ) { if ( id == null ) {
throw new TransientObjectException( throw new TransientObjectException(

View File

@ -68,7 +68,7 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
EntityPersister persister, EntityPersister persister,
Serializable id, Serializable id,
EntityMode entityMode, EntityMode entityMode,
SessionFactoryImplementor factory) throws HibernateException { SessionImplementor session) throws HibernateException {
if ( id != null && id instanceof DelayedPostInsertIdentifier ) { if ( id != null && id instanceof DelayedPostInsertIdentifier ) {
// this is a situation where the entity id is assigned by a post-insert generator // this is a situation where the entity id is assigned by a post-insert generator
@ -78,11 +78,11 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
if ( persister.canExtractIdOutOfEntity() ) { if ( persister.canExtractIdOutOfEntity() ) {
Serializable oid = persister.getIdentifier( object, entityMode ); Serializable oid = persister.getIdentifier( object, session );
if (id==null) { if (id==null) {
throw new AssertionFailure("null id in " + persister.getEntityName() + " entry (don't flush the Session after an exception occurs)"); throw new AssertionFailure("null id in " + persister.getEntityName() + " entry (don't flush the Session after an exception occurs)");
} }
if ( !persister.getIdentifierType().isEqual( id, oid, entityMode, factory ) ) { if ( !persister.getIdentifierType().isEqual( id, oid, entityMode, session.getFactory() ) ) {
throw new HibernateException( throw new HibernateException(
"identifier of an instance of " + "identifier of an instance of " +
persister.getEntityName() + persister.getEntityName() +
@ -174,8 +174,7 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
EntityEntry entry, EntityEntry entry,
EntityMode entityMode, EntityMode entityMode,
boolean mightBeDirty, boolean mightBeDirty,
SessionImplementor session SessionImplementor session) {
) {
final Object[] loadedState = entry.getLoadedState(); final Object[] loadedState = entry.getLoadedState();
final Status status = entry.getStatus(); final Status status = entry.getStatus();
final EntityPersister persister = entry.getPersister(); final EntityPersister persister = entry.getPersister();
@ -189,7 +188,7 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
values = loadedState; values = loadedState;
} }
else { else {
checkId( entity, persister, entry.getId(), entityMode, session.getFactory() ); checkId( entity, persister, entry.getId(), entityMode, session );
// grab its current state // grab its current state
values = persister.getPropertyValues( entity, entityMode ); values = persister.getPropertyValues( entity, entityMode );

View File

@ -71,7 +71,7 @@ public class DefaultLockEventListener extends AbstractLockUpgradeEventListener i
EntityEntry entry = source.getPersistenceContext().getEntry(entity); EntityEntry entry = source.getPersistenceContext().getEntry(entity);
if (entry==null) { if (entry==null) {
final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity ); final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
final Serializable id = persister.getIdentifier( entity, source.getEntityMode() ); final Serializable id = persister.getIdentifier( entity, source );
if ( !ForeignKeys.isNotTransient( event.getEntityName(), entity, Boolean.FALSE, source ) ) { if ( !ForeignKeys.isNotTransient( event.getEntityName(), entity, Boolean.FALSE, source ) ) {
throw new TransientObjectException( throw new TransientObjectException(
"cannot lock an unsaved transient instance: " + "cannot lock an unsaved transient instance: " +

View File

@ -209,7 +209,7 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener
EntityEntry entry = source.getPersistenceContext().getEntry( entity ); EntityEntry entry = source.getPersistenceContext().getEntry( entity );
if ( entry == null ) { if ( entry == null ) {
EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity ); EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
Serializable id = persister.getIdentifier( entity, source.getEntityMode() ); Serializable id = persister.getIdentifier( entity, source );
if ( id != null ) { if ( id != null ) {
EntityKey key = new EntityKey( id, persister, source.getEntityMode() ); EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
Object managedEntity = source.getPersistenceContext().getEntity( key ); Object managedEntity = source.getPersistenceContext().getEntity( key );
@ -289,7 +289,7 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener
final EntityPersister persister = source.getEntityPersister( entityName, entity ); final EntityPersister persister = source.getEntityPersister( entityName, entity );
final Serializable id = persister.hasIdentifierProperty() ? final Serializable id = persister.hasIdentifierProperty() ?
persister.getIdentifier( entity, source.getEntityMode() ) : persister.getIdentifier( entity, source ) :
null; null;
if ( copyCache.containsKey( entity ) ) { if ( copyCache.containsKey( entity ) ) {
persister.setIdentifier( copyCache.get( entity ), id, source ); persister.setIdentifier( copyCache.get( entity ), id, source );
@ -367,11 +367,11 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener
Serializable id = event.getRequestedId(); Serializable id = event.getRequestedId();
if ( id == null ) { if ( id == null ) {
id = persister.getIdentifier( entity, source.getEntityMode() ); id = persister.getIdentifier( entity, source );
} }
else { else {
// check that entity id = requestedId // check that entity id = requestedId
Serializable entityId = persister.getIdentifier( entity, source.getEntityMode() ); Serializable entityId = persister.getIdentifier( entity, source );
if ( !persister.getIdentifierType().isEqual( id, entityId, source.getEntityMode(), source.getFactory() ) ) { if ( !persister.getIdentifierType().isEqual( id, entityId, source.getEntityMode(), source.getFactory() ) ) {
throw new HibernateException( "merge requested with id not matching id of passed entity" ); throw new HibernateException( "merge requested with id not matching id of passed entity" );
} }
@ -468,7 +468,7 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener
private boolean existsInDatabase(Object entity, EventSource source, EntityPersister persister) { private boolean existsInDatabase(Object entity, EventSource source, EntityPersister persister) {
EntityEntry entry = source.getPersistenceContext().getEntry( entity ); EntityEntry entry = source.getPersistenceContext().getEntry( entity );
if ( entry == null ) { if ( entry == null ) {
Serializable id = persister.getIdentifier( entity, source.getEntityMode() ); Serializable id = persister.getIdentifier( entity, source );
if ( id != null ) { if ( id != null ) {
EntityKey key = new EntityKey( id, persister, source.getEntityMode() ); EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
Object managedEntity = source.getPersistenceContext().getEntity( key ); Object managedEntity = source.getPersistenceContext().getEntity( key );

View File

@ -92,7 +92,7 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
if ( e == null ) { if ( e == null ) {
persister = source.getEntityPersister(null, object); //refresh() does not pass an entityName persister = source.getEntityPersister(null, object); //refresh() does not pass an entityName
id = persister.getIdentifier( object, event.getSession().getEntityMode() ); id = persister.getIdentifier( object, event.getSession() );
if ( log.isTraceEnabled() ) { if ( log.isTraceEnabled() ) {
log.trace( log.trace(
"refreshing transient " + "refreshing transient " +

View File

@ -83,7 +83,7 @@ public class DefaultReplicateEventListener extends AbstractSaveEventListener imp
/*if ( persister.isUnsaved(entity, source) ) { /*if ( persister.isUnsaved(entity, source) ) {
throw new TransientObjectException("transient instance passed to replicate()"); throw new TransientObjectException("transient instance passed to replicate()");
}*/ }*/
Serializable id = persister.getIdentifier( entity, source.getEntityMode() ); Serializable id = persister.getIdentifier( entity, source );
if ( id == null ) { if ( id == null ) {
throw new TransientObjectException( "instance with null id passed to replicate()" ); throw new TransientObjectException( "instance with null id passed to replicate()" );
} }

View File

@ -265,7 +265,7 @@ public class DefaultSaveOrUpdateEventListener extends AbstractSaveEventListener
Serializable requestedId, Serializable requestedId,
SessionImplementor session) { SessionImplementor session) {
// use the id assigned to the instance // use the id assigned to the instance
Serializable id = persister.getIdentifier( entity, session.getEntityMode() ); Serializable id = persister.getIdentifier( entity, session );
if ( id == null ) { if ( id == null ) {
// assume this is a newly instantiated transient object // assume this is a newly instantiated transient object
// which should be saved rather than updated // which should be saved rather than updated

View File

@ -47,25 +47,20 @@ public class Assigned implements IdentifierGenerator, Configurable {
private String entityName; private String entityName;
public Serializable generate(SessionImplementor session, Object obj) throws HibernateException { public Serializable generate(SessionImplementor session, Object obj) throws HibernateException {
//TODO: cache the persister, this shows up in yourkit
final Serializable id = session.getEntityPersister( entityName, obj ) final Serializable id = session.getEntityPersister( entityName, obj ).getIdentifier( obj, session );
//TODO: cache the persister, this shows up in yourkit if ( id == null ) {
.getIdentifier( obj, session.getEntityMode() );
if (id==null) {
throw new IdentifierGenerationException( throw new IdentifierGenerationException(
"ids for this class must be manually assigned before calling save(): " + "ids for this class must be manually assigned before calling save(): " + entityName
entityName
); );
} }
return id; return id;
} }
public void configure(Type type, Properties params, Dialect d) public void configure(Type type, Properties params, Dialect d) throws MappingException {
throws MappingException {
entityName = params.getProperty(ENTITY_NAME); entityName = params.getProperty(ENTITY_NAME);
if (entityName==null) { if ( entityName == null ) {
throw new MappingException("no entity name"); throw new MappingException("no entity name");
} }
} }

View File

@ -129,7 +129,7 @@ public class StatelessSessionImpl extends AbstractSessionImpl
public void delete(String entityName, Object entity) { public void delete(String entityName, Object entity) {
errorIfClosed(); errorIfClosed();
EntityPersister persister = getEntityPersister(entityName, entity); EntityPersister persister = getEntityPersister(entityName, entity);
Serializable id = persister.getIdentifier(entity, EntityMode.POJO); Serializable id = persister.getIdentifier( entity, this );
Object version = persister.getVersion(entity, EntityMode.POJO); Object version = persister.getVersion(entity, EntityMode.POJO);
persister.delete(id, version, entity, this); persister.delete(id, version, entity, this);
} }
@ -145,7 +145,7 @@ public class StatelessSessionImpl extends AbstractSessionImpl
public void update(String entityName, Object entity) { public void update(String entityName, Object entity) {
errorIfClosed(); errorIfClosed();
EntityPersister persister = getEntityPersister(entityName, entity); EntityPersister persister = getEntityPersister(entityName, entity);
Serializable id = persister.getIdentifier(entity, EntityMode.POJO); Serializable id = persister.getIdentifier( entity, this );
Object[] state = persister.getPropertyValues(entity, EntityMode.POJO); Object[] state = persister.getPropertyValues(entity, EntityMode.POJO);
Object oldVersion; Object oldVersion;
if ( persister.isVersioned() ) { if ( persister.isVersioned() ) {
@ -197,7 +197,7 @@ public class StatelessSessionImpl extends AbstractSessionImpl
public void refresh(String entityName, Object entity, LockMode lockMode) { public void refresh(String entityName, Object entity, LockMode lockMode) {
final EntityPersister persister = this.getEntityPersister( entityName, entity ); final EntityPersister persister = this.getEntityPersister( entityName, entity );
final Serializable id = persister.getIdentifier( entity, getEntityMode() ); final Serializable id = persister.getIdentifier( entity, this );
if ( log.isTraceEnabled() ) { if ( log.isTraceEnabled() ) {
log.trace( log.trace(
"refreshing transient " + "refreshing transient " +

View File

@ -419,8 +419,7 @@ public class Component extends SimpleValue implements MetaAttributable {
} }
public Serializable locateGenerationContext(SessionImplementor session, Object incomingObject) { public Serializable locateGenerationContext(SessionImplementor session, Object incomingObject) {
return session.getEntityPersister( entityName, incomingObject ) return session.getEntityPersister( entityName, incomingObject ).getIdentifier( incomingObject, session );
.getIdentifier( incomingObject, session.getEntityMode() );
} }
} }

View File

@ -195,8 +195,20 @@ public interface ClassMetadata {
/** /**
* Get the identifier of an instance (throw an exception if no identifier property) * Get the identifier of an instance (throw an exception if no identifier property)
* @deprecated Use {@link #getIdentifier(Object,SessionImplementor)} instead
* @noinspection JavaDoc
*/ */
public Serializable getIdentifier(Object entity, EntityMode entityMode) throws HibernateException; public Serializable getIdentifier(Object object, EntityMode entityMode) throws HibernateException;
/**
* Get the identifier of an instance (throw an exception if no identifier property)
*
* @param entity The entity for which to get the identifier
* @param session The session from which the request originated
*
* @return The identifier
*/
public Serializable getIdentifier(Object entity, SessionImplementor session);
/** /**
* Inject the identifier value into the given entity. * Inject the identifier value into the given entity.

View File

@ -3514,7 +3514,7 @@ public abstract class AbstractEntityPersister
public Boolean isTransient(Object entity, SessionImplementor session) throws HibernateException { public Boolean isTransient(Object entity, SessionImplementor session) throws HibernateException {
final Serializable id; final Serializable id;
if ( canExtractIdOutOfEntity() ) { if ( canExtractIdOutOfEntity() ) {
id = getIdentifier( entity, session.getEntityMode() ); id = getIdentifier( entity, session );
} }
else { else {
id = null; id = null;
@ -3796,9 +3796,12 @@ public abstract class AbstractEntityPersister
return getTuplizer( entityMode ).getPropertyValue( object, propertyName ); return getTuplizer( entityMode ).getPropertyValue( object, propertyName );
} }
public Serializable getIdentifier(Object object, EntityMode entityMode) public Serializable getIdentifier(Object object, EntityMode entityMode) throws HibernateException {
throws HibernateException { return getTuplizer( entityMode ).getIdentifier( object, null );
return getTuplizer( entityMode ).getIdentifier( object ); }
public Serializable getIdentifier(Object entity, SessionImplementor session) {
return getTuplizer( session.getEntityMode() ).getIdentifier( entity, session );
} }
/** /**

View File

@ -652,9 +652,21 @@ public interface EntityPersister extends OptimisticCacheSource {
/** /**
* Get the identifier of an instance (throw an exception if no identifier property) * Get the identifier of an instance (throw an exception if no identifier property)
* @deprecated Use {@link #getIdentifier(Object,SessionImplementor)} instead
* @noinspection JavaDoc
*/ */
public Serializable getIdentifier(Object object, EntityMode entityMode) throws HibernateException; public Serializable getIdentifier(Object object, EntityMode entityMode) throws HibernateException;
/**
* Get the identifier of an instance (throw an exception if no identifier property)
*
* @param entity The entity for which to get the identifier
* @param session The session from which the request originated
*
* @return The identifier
*/
public Serializable getIdentifier(Object entity, SessionImplementor session);
/** /**
* Inject the identifier value into the given entity. * Inject the identifier value into the given entity.
* </p> * </p>

View File

@ -28,12 +28,20 @@ import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.EntityMode; import org.hibernate.EntityMode;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.engine.Cascade;
import org.hibernate.engine.EntityEntry;
import org.hibernate.engine.EntityKey; import org.hibernate.engine.EntityKey;
import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor; import org.hibernate.engine.SessionImplementor;
import org.hibernate.event.EventSource;
import org.hibernate.event.PersistEvent;
import org.hibernate.event.SaveOrUpdateEvent;
import org.hibernate.id.Assigned; import org.hibernate.id.Assigned;
import org.hibernate.intercept.LazyPropertyInitializer; import org.hibernate.intercept.LazyPropertyInitializer;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
@ -42,6 +50,7 @@ import org.hibernate.mapping.Property;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.property.Getter; import org.hibernate.property.Getter;
import org.hibernate.property.Setter; import org.hibernate.property.Setter;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.ProxyFactory; import org.hibernate.proxy.ProxyFactory;
import org.hibernate.tuple.Instantiator; import org.hibernate.tuple.Instantiator;
import org.hibernate.tuple.StandardProperty; import org.hibernate.tuple.StandardProperty;
@ -60,6 +69,8 @@ import org.hibernate.type.Type;
*/ */
public abstract class AbstractEntityTuplizer implements EntityTuplizer { public abstract class AbstractEntityTuplizer implements EntityTuplizer {
private static final Logger log = LoggerFactory.getLogger( AbstractEntityTuplizer.class );
//TODO: currently keeps Getters and Setters (instead of PropertyAccessors) because of the way getGetter() and getSetter() are implemented currently; yuck! //TODO: currently keeps Getters and Setters (instead of PropertyAccessors) because of the way getGetter() and getSetter() are implemented currently; yuck!
private final EntityMetamodel entityMetamodel; private final EntityMetamodel entityMetamodel;
@ -198,6 +209,10 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
} }
public Serializable getIdentifier(Object entity) throws HibernateException { public Serializable getIdentifier(Object entity) throws HibernateException {
return getIdentifier( entity, null );
}
public Serializable getIdentifier(Object entity, SessionImplementor session) {
final Object id; final Object id;
if ( entityMetamodel.getIdentifierProperty().isEmbedded() ) { if ( entityMetamodel.getIdentifierProperty().isEmbedded() ) {
id = entity; id = entity;
@ -208,7 +223,7 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
throw new HibernateException( "The class has no identifier property: " + getEntityName() ); throw new HibernateException( "The class has no identifier property: " + getEntityName() );
} }
else { else {
id = mappedIdentifierValueMarshaller.getIdentifier( entity, getEntityMode(), getFactory() ); id = mappedIdentifierValueMarshaller.getIdentifier( entity, getEntityMode(), session );
} }
} }
else { else {
@ -255,13 +270,13 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
idSetter.set( entity, id, getFactory() ); idSetter.set( entity, id, getFactory() );
} }
else if ( identifierMapperType != null ) { else if ( identifierMapperType != null ) {
mappedIdentifierValueMarshaller.setIdentifier( entity, id, session ); mappedIdentifierValueMarshaller.setIdentifier( entity, id, getEntityMode(), session );
} }
} }
private static interface MappedIdentifierValueMarshaller { private static interface MappedIdentifierValueMarshaller {
public Object getIdentifier(Object entity, EntityMode entityMode, SessionFactoryImplementor factory); public Object getIdentifier(Object entity, EntityMode entityMode, SessionImplementor session);
public void setIdentifier(Object entity, Serializable id, SessionImplementor session); public void setIdentifier(Object entity, Serializable id, EntityMode entityMode, SessionImplementor session);
} }
private final MappedIdentifierValueMarshaller mappedIdentifierValueMarshaller; private final MappedIdentifierValueMarshaller mappedIdentifierValueMarshaller;
@ -304,18 +319,18 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
this.mappedIdentifierType = mappedIdentifierType; this.mappedIdentifierType = mappedIdentifierType;
} }
public Object getIdentifier(Object entity, EntityMode entityMode, SessionFactoryImplementor factory) { public Object getIdentifier(Object entity, EntityMode entityMode, SessionImplementor session) {
Object id = mappedIdentifierType.instantiate( entityMode ); Object id = mappedIdentifierType.instantiate( entityMode );
final Object[] propertyValues = virtualIdComponent.getPropertyValues( entity, entityMode ); final Object[] propertyValues = virtualIdComponent.getPropertyValues( entity, entityMode );
mappedIdentifierType.setPropertyValues( id, propertyValues, entityMode ); mappedIdentifierType.setPropertyValues( id, propertyValues, entityMode );
return id; return id;
} }
public void setIdentifier(Object entity, Serializable id, SessionImplementor session) { public void setIdentifier(Object entity, Serializable id, EntityMode entityMode, SessionImplementor session) {
virtualIdComponent.setPropertyValues( virtualIdComponent.setPropertyValues(
entity, entity,
mappedIdentifierType.getPropertyValues( id, session ), mappedIdentifierType.getPropertyValues( id, session ),
session.getEntityMode() entityMode
); );
} }
} }
@ -329,47 +344,79 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
this.mappedIdentifierType = mappedIdentifierType; this.mappedIdentifierType = mappedIdentifierType;
} }
public Object getIdentifier(Object entity, EntityMode entityMode, SessionFactoryImplementor factory) { public Object getIdentifier(Object entity, EntityMode entityMode, SessionImplementor session) {
Object id = mappedIdentifierType.instantiate( entityMode ); final Object id = mappedIdentifierType.instantiate( entityMode );
final Object[] propertyValues = virtualIdComponent.getPropertyValues( entity, entityMode ); final Object[] propertyValues = virtualIdComponent.getPropertyValues( entity, entityMode );
Type[] subTypes = virtualIdComponent.getSubtypes(); final Type[] subTypes = virtualIdComponent.getSubtypes();
Type[] copierSubTypes = mappedIdentifierType.getSubtypes(); final Type[] copierSubTypes = mappedIdentifierType.getSubtypes();
final int length = subTypes.length; final int length = subTypes.length;
for ( int i = 0 ; i < length; i++ ) { for ( int i = 0 ; i < length; i++ ) {
if ( propertyValues[i] == null ) { if ( propertyValues[i] == null ) {
continue; throw new HibernateException( "No part of a composite identifier may be null" );
} }
//JPA 2 in @IdClass points to the pk of the entity //JPA 2 @MapsId + @IdClass points to the pk of the entity
if ( subTypes[i].isAssociationType() && ! copierSubTypes[i].isAssociationType() ) { if ( subTypes[i].isAssociationType() && ! copierSubTypes[i].isAssociationType() ) {
final String associatedEntityName = ( ( EntityType ) subTypes[i] ).getAssociatedEntityName(); // we need a session to handle this use case
final EntityPersister entityPersister = factory.getEntityPersister( associatedEntityName ); if ( session == null ) {
propertyValues[i] = entityPersister.getIdentifier( propertyValues[i], entityMode ); throw new AssertionError(
"Deprecated version of getIdentifier (no session) was used but session was required"
);
}
final Object subId;
if ( HibernateProxy.class.isInstance( propertyValues[i] ) ) {
subId = ( (HibernateProxy) propertyValues[i] ).getHibernateLazyInitializer().getIdentifier();
}
else {
EntityEntry pcEntry = session.getPersistenceContext().getEntry( propertyValues[i] );
if ( pcEntry != null ) {
subId = pcEntry.getId();
}
else {
log.debug( "Performing implicit derived identity cascade" );
final PersistEvent event = new PersistEvent( null, propertyValues[i], (EventSource) session );
for ( int x = 0; x < session.getListeners().getPersistEventListeners().length; x++ ) {
session.getListeners().getPersistEventListeners()[x].onPersist( event );
}
pcEntry = session.getPersistenceContext().getEntry( propertyValues[i] );
if ( pcEntry == null || pcEntry.getId() == null ) {
throw new HibernateException( "Unable to process implicit derived identity cascade" );
}
else {
subId = pcEntry.getId();
}
}
}
propertyValues[i] = subId;
} }
} }
mappedIdentifierType.setPropertyValues( id, propertyValues, entityMode ); mappedIdentifierType.setPropertyValues( id, propertyValues, entityMode );
return id; return id;
} }
public void setIdentifier(Object entity, Serializable id, SessionImplementor session) { public void setIdentifier(Object entity, Serializable id, EntityMode entityMode, SessionImplementor session) {
final Object[] extractedValues = mappedIdentifierType.getPropertyValues( id, session.getEntityMode() ); final Object[] extractedValues = mappedIdentifierType.getPropertyValues( id, entityMode );
final Object[] injectionValues = new Object[ extractedValues.length ]; final Object[] injectionValues = new Object[ extractedValues.length ];
for ( int i = 0; i < virtualIdComponent.getSubtypes().length; i++ ) { for ( int i = 0; i < virtualIdComponent.getSubtypes().length; i++ ) {
final Type virtualPropertyType = virtualIdComponent.getSubtypes()[i]; final Type virtualPropertyType = virtualIdComponent.getSubtypes()[i];
final Type idClassPropertyType = mappedIdentifierType.getSubtypes()[i]; final Type idClassPropertyType = mappedIdentifierType.getSubtypes()[i];
if ( virtualPropertyType.isEntityType() && ! idClassPropertyType.isEntityType() ) { if ( virtualPropertyType.isEntityType() && ! idClassPropertyType.isEntityType() ) {
if ( session == null ) {
throw new AssertionError(
"Deprecated version of getIdentifier (no session) was used but session was required"
);
}
final String associatedEntityName = ( (EntityType) virtualPropertyType ).getAssociatedEntityName(); final String associatedEntityName = ( (EntityType) virtualPropertyType ).getAssociatedEntityName();
final EntityKey entityKey = new EntityKey( final EntityKey entityKey = new EntityKey(
(Serializable) extractedValues[i], (Serializable) extractedValues[i],
session.getFactory().getEntityPersister( associatedEntityName ), session.getFactory().getEntityPersister( associatedEntityName ),
session.getEntityMode() entityMode
); );
// it is conceivable there is a proxy, so check that first // it is conceivable there is a proxy, so check that first
Object association = session.getPersistenceContext() Object association = session.getPersistenceContext().getProxy( entityKey );
.getProxy( entityKey );
if ( association == null ) { if ( association == null ) {
// otherwise look for an initialized version // otherwise look for an initialized version
association = session.getPersistenceContext() association = session.getPersistenceContext().getEntity( entityKey );
.getEntity( entityKey );
} }
injectionValues[i] = association; injectionValues[i] = association;
} }

View File

@ -24,6 +24,7 @@
*/ */
package org.hibernate.tuple.entity; package org.hibernate.tuple.entity;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property; import org.hibernate.mapping.Property;
import org.hibernate.proxy.ProxyFactory; import org.hibernate.proxy.ProxyFactory;
@ -117,15 +118,22 @@ public class Dom4jEntityTuplizer extends AbstractEntityTuplizer {
* {@inheritDoc} * {@inheritDoc}
*/ */
public Serializable getIdentifier(Object entityOrId) throws HibernateException { public Serializable getIdentifier(Object entityOrId) throws HibernateException {
if (entityOrId instanceof Element) { return getIdentifier( entityOrId, null );
return super.getIdentifier(entityOrId); }
/**
* {@inheritDoc}
*/
public Serializable getIdentifier(Object entityOrId, SessionImplementor session) {
if ( entityOrId instanceof Element ) {
return super.getIdentifier( entityOrId, session );
} }
else { else {
//it was not embedded, so the argument is just an id //it was not embedded, so the argument is just an id
return (Serializable) entityOrId; return (Serializable) entityOrId;
} }
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */

View File

@ -79,12 +79,26 @@ public interface EntityTuplizer extends Tuplizer {
* Extract the identifier value from the given entity. * Extract the identifier value from the given entity.
* *
* @param entity The entity from which to extract the identifier value. * @param entity The entity from which to extract the identifier value.
*
* @return The identifier value. * @return The identifier value.
*
* @throws HibernateException If the entity does not define an identifier property, or an * @throws HibernateException If the entity does not define an identifier property, or an
* error occurrs accessing its value. * error occurs accessing its value.
*
* @deprecated Use {@link #getIdentifier(Object,SessionImplementor)} instead.
*/ */
public Serializable getIdentifier(Object entity) throws HibernateException; public Serializable getIdentifier(Object entity) throws HibernateException;
/**
* Extract the identifier value from the given entity.
*
* @param entity The entity from which to extract the identifier value.
* @param session The session from which is requests originates
*
* @return The identifier value.
*/
public Serializable getIdentifier(Object entity, SessionImplementor session);
/** /**
* Inject the identifier value into the given entity. * Inject the identifier value into the given entity.
* </p> * </p>

View File

@ -403,7 +403,7 @@ public abstract class CollectionType extends AbstractType implements Association
if ( ownerMappedClass.isAssignableFrom( keyType.getReturnedClass() ) && if ( ownerMappedClass.isAssignableFrom( keyType.getReturnedClass() ) &&
keyType.getReturnedClass().isInstance( key ) ) { keyType.getReturnedClass().isInstance( key ) ) {
// the key is the owning entity itself, so get the ID from the key // the key is the owning entity itself, so get the ID from the key
ownerId = ownerPersister.getIdentifier( key, session.getEntityMode() ); ownerId = ownerPersister.getIdentifier( key, session );
} }
else { else {
// TODO: check if key contains the owner ID // TODO: check if key contains the owner ID

View File

@ -60,7 +60,7 @@ public class EJB3DeleteEventListener extends DefaultDeleteEventListener implemen
EventSource source = event.getSession(); EventSource source = event.getSession();
String entityName = event.getEntityName(); String entityName = event.getEntityName();
EntityPersister persister = source.getEntityPersister( entityName, event.getObject() ); EntityPersister persister = source.getEntityPersister( entityName, event.getObject() );
Serializable id = persister.getIdentifier( event.getObject(), source.getEntityMode() ); Serializable id = persister.getIdentifier( event.getObject(), source );
entityName = entityName == null ? source.guessEntityName( event.getObject() ) : entityName; entityName = entityName == null ? source.guessEntityName( event.getObject() ) : entityName;
throw new IllegalArgumentException("Removing a detached instance "+ entityName + "#" + id); throw new IllegalArgumentException("Removing a detached instance "+ entityName + "#" + id);
} }

View File

@ -64,7 +64,7 @@ public class Tools {
} }
return session.getEntityPersister(null, obj).getIdentifier(obj, session.getEntityMode()); return session.getEntityPersister( null, obj ).getIdentifier( obj, session );
} }
public static Object getTargetFromProxy(SessionFactoryImplementor sessionFactoryImplementor, HibernateProxy proxy) { public static Object getTargetFromProxy(SessionFactoryImplementor sessionFactoryImplementor, HibernateProxy proxy) {

View File

@ -182,6 +182,11 @@ public class CustomPersister implements EntityPersister {
return ( (Custom) object ).id; return ( (Custom) object ).id;
} }
public Serializable getIdentifier(Object entity, SessionImplementor session) {
checkEntityMode( session );
return ( (Custom) entity ).id;
}
public void setIdentifier(Object object, Serializable id, EntityMode entityMode) throws HibernateException { public void setIdentifier(Object object, Serializable id, EntityMode entityMode) throws HibernateException {
checkEntityMode( entityMode ); checkEntityMode( entityMode );
( (Custom) object ).id = (String) id; ( (Custom) object ).id = (String) id;