diff --git a/core/src/main/java/org/hibernate/engine/Cascade.java b/core/src/main/java/org/hibernate/engine/Cascade.java index e231f147ba..02e1fb0b7e 100644 --- a/core/src/main/java/org/hibernate/engine/Cascade.java +++ b/core/src/main/java/org/hibernate/engine/Cascade.java @@ -251,8 +251,7 @@ public final class Cascade { if ( loadedValue != null ) { final String entityName = entry.getPersister().getEntityName(); if ( log.isTraceEnabled() ) { - final Serializable id = entry.getPersister() - .getIdentifier( loadedValue, eventSource.getEntityMode() ); + final Serializable id = entry.getPersister().getIdentifier( loadedValue, eventSource ); final String description = MessageHelper.infoString( entityName, id ); log.trace( "deleting orphaned entity instance: " + description ); } diff --git a/core/src/main/java/org/hibernate/engine/Collections.java b/core/src/main/java/org/hibernate/engine/Collections.java index 9e97296bc7..019c12cc14 100755 --- a/core/src/main/java/org/hibernate/engine/Collections.java +++ b/core/src/main/java/org/hibernate/engine/Collections.java @@ -85,8 +85,7 @@ public final class Collections { boolean hasOrphanDelete = loadedPersister != null && loadedPersister.hasOrphanDelete(); if (hasOrphanDelete) { - Serializable ownerId = loadedPersister.getOwnerEntityPersister() - .getIdentifier( coll.getOwner(), session.getEntityMode() ); + Serializable ownerId = loadedPersister.getOwnerEntityPersister().getIdentifier( coll.getOwner(), session ); if ( ownerId == null ) { // 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 diff --git a/core/src/main/java/org/hibernate/engine/ForeignKeys.java b/core/src/main/java/org/hibernate/engine/ForeignKeys.java index 09da7a18a9..10346202aa 100755 --- a/core/src/main/java/org/hibernate/engine/ForeignKeys.java +++ b/core/src/main/java/org/hibernate/engine/ForeignKeys.java @@ -209,8 +209,10 @@ public final class ForeignKeys { if (assumed!=null) return assumed.booleanValue(); // hit the database, after checking the session cache for a snapshot - Object[] snapshot = session.getPersistenceContext() - .getDatabaseSnapshot( persister.getIdentifier( entity, session.getEntityMode() ), persister ); + Object[] snapshot = session.getPersistenceContext().getDatabaseSnapshot( + persister.getIdentifier( entity, session ), + persister + ); return snapshot==null; } @@ -244,7 +246,7 @@ public final class ForeignKeys { (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; } diff --git a/core/src/main/java/org/hibernate/event/def/DefaultDeleteEventListener.java b/core/src/main/java/org/hibernate/event/def/DefaultDeleteEventListener.java index 6f395de793..a32915a36e 100644 --- a/core/src/main/java/org/hibernate/event/def/DefaultDeleteEventListener.java +++ b/core/src/main/java/org/hibernate/event/def/DefaultDeleteEventListener.java @@ -108,7 +108,7 @@ public class DefaultDeleteEventListener implements DeleteEventListener { performDetachedEntityDeletionCheck( event ); } - id = persister.getIdentifier( entity, source.getEntityMode() ); + id = persister.getIdentifier( entity, source ); if ( id == null ) { throw new TransientObjectException( diff --git a/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java b/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java index eab1b31f39..8a60da2bb0 100755 --- a/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java +++ b/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java @@ -68,7 +68,7 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener EntityPersister persister, Serializable id, EntityMode entityMode, - SessionFactoryImplementor factory) throws HibernateException { + SessionImplementor session) throws HibernateException { if ( id != null && id instanceof DelayedPostInsertIdentifier ) { // 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() ) { - Serializable oid = persister.getIdentifier( object, entityMode ); + Serializable oid = persister.getIdentifier( object, session ); if (id==null) { 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( "identifier of an instance of " + persister.getEntityName() + @@ -174,8 +174,7 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener EntityEntry entry, EntityMode entityMode, boolean mightBeDirty, - SessionImplementor session - ) { + SessionImplementor session) { final Object[] loadedState = entry.getLoadedState(); final Status status = entry.getStatus(); final EntityPersister persister = entry.getPersister(); @@ -189,7 +188,7 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener values = loadedState; } else { - checkId( entity, persister, entry.getId(), entityMode, session.getFactory() ); + checkId( entity, persister, entry.getId(), entityMode, session ); // grab its current state values = persister.getPropertyValues( entity, entityMode ); diff --git a/core/src/main/java/org/hibernate/event/def/DefaultLockEventListener.java b/core/src/main/java/org/hibernate/event/def/DefaultLockEventListener.java index c7b3bf2590..39fc1e9c22 100644 --- a/core/src/main/java/org/hibernate/event/def/DefaultLockEventListener.java +++ b/core/src/main/java/org/hibernate/event/def/DefaultLockEventListener.java @@ -71,7 +71,7 @@ public class DefaultLockEventListener extends AbstractLockUpgradeEventListener i EntityEntry entry = source.getPersistenceContext().getEntry(entity); if (entry==null) { 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 ) ) { throw new TransientObjectException( "cannot lock an unsaved transient instance: " + diff --git a/core/src/main/java/org/hibernate/event/def/DefaultMergeEventListener.java b/core/src/main/java/org/hibernate/event/def/DefaultMergeEventListener.java index 5d523190d2..46a2074bc5 100755 --- a/core/src/main/java/org/hibernate/event/def/DefaultMergeEventListener.java +++ b/core/src/main/java/org/hibernate/event/def/DefaultMergeEventListener.java @@ -209,7 +209,7 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener EntityEntry entry = source.getPersistenceContext().getEntry( entity ); if ( entry == null ) { EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity ); - Serializable id = persister.getIdentifier( entity, source.getEntityMode() ); + Serializable id = persister.getIdentifier( entity, source ); if ( id != null ) { EntityKey key = new EntityKey( id, persister, source.getEntityMode() ); Object managedEntity = source.getPersistenceContext().getEntity( key ); @@ -289,7 +289,7 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener final EntityPersister persister = source.getEntityPersister( entityName, entity ); final Serializable id = persister.hasIdentifierProperty() ? - persister.getIdentifier( entity, source.getEntityMode() ) : + persister.getIdentifier( entity, source ) : null; if ( copyCache.containsKey( entity ) ) { persister.setIdentifier( copyCache.get( entity ), id, source ); @@ -367,11 +367,11 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener Serializable id = event.getRequestedId(); if ( id == null ) { - id = persister.getIdentifier( entity, source.getEntityMode() ); + id = persister.getIdentifier( entity, source ); } else { // 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() ) ) { 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) { EntityEntry entry = source.getPersistenceContext().getEntry( entity ); if ( entry == null ) { - Serializable id = persister.getIdentifier( entity, source.getEntityMode() ); + Serializable id = persister.getIdentifier( entity, source ); if ( id != null ) { EntityKey key = new EntityKey( id, persister, source.getEntityMode() ); Object managedEntity = source.getPersistenceContext().getEntity( key ); diff --git a/core/src/main/java/org/hibernate/event/def/DefaultRefreshEventListener.java b/core/src/main/java/org/hibernate/event/def/DefaultRefreshEventListener.java index 6e252c410e..de4e8e7ccd 100644 --- a/core/src/main/java/org/hibernate/event/def/DefaultRefreshEventListener.java +++ b/core/src/main/java/org/hibernate/event/def/DefaultRefreshEventListener.java @@ -92,7 +92,7 @@ public class DefaultRefreshEventListener implements RefreshEventListener { if ( e == null ) { 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() ) { log.trace( "refreshing transient " + diff --git a/core/src/main/java/org/hibernate/event/def/DefaultReplicateEventListener.java b/core/src/main/java/org/hibernate/event/def/DefaultReplicateEventListener.java index a3d1c8324c..0ea32de140 100644 --- a/core/src/main/java/org/hibernate/event/def/DefaultReplicateEventListener.java +++ b/core/src/main/java/org/hibernate/event/def/DefaultReplicateEventListener.java @@ -83,7 +83,7 @@ public class DefaultReplicateEventListener extends AbstractSaveEventListener imp /*if ( persister.isUnsaved(entity, source) ) { throw new TransientObjectException("transient instance passed to replicate()"); }*/ - Serializable id = persister.getIdentifier( entity, source.getEntityMode() ); + Serializable id = persister.getIdentifier( entity, source ); if ( id == null ) { throw new TransientObjectException( "instance with null id passed to replicate()" ); } diff --git a/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java b/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java index 82e2f015ec..3b3e1bc44a 100755 --- a/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java +++ b/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java @@ -265,7 +265,7 @@ public class DefaultSaveOrUpdateEventListener extends AbstractSaveEventListener Serializable requestedId, SessionImplementor session) { // use the id assigned to the instance - Serializable id = persister.getIdentifier( entity, session.getEntityMode() ); + Serializable id = persister.getIdentifier( entity, session ); if ( id == null ) { // assume this is a newly instantiated transient object // which should be saved rather than updated diff --git a/core/src/main/java/org/hibernate/id/Assigned.java b/core/src/main/java/org/hibernate/id/Assigned.java index 61186419ab..db8d483439 100644 --- a/core/src/main/java/org/hibernate/id/Assigned.java +++ b/core/src/main/java/org/hibernate/id/Assigned.java @@ -47,25 +47,20 @@ public class Assigned implements IdentifierGenerator, Configurable { private String entityName; public Serializable generate(SessionImplementor session, Object obj) throws HibernateException { - - final Serializable id = session.getEntityPersister( entityName, obj ) - //TODO: cache the persister, this shows up in yourkit - .getIdentifier( obj, session.getEntityMode() ); - - if (id==null) { + //TODO: cache the persister, this shows up in yourkit + final Serializable id = session.getEntityPersister( entityName, obj ).getIdentifier( obj, session ); + if ( id == null ) { throw new IdentifierGenerationException( - "ids for this class must be manually assigned before calling save(): " + - entityName + "ids for this class must be manually assigned before calling save(): " + entityName ); } return id; } - public void configure(Type type, Properties params, Dialect d) - throws MappingException { + public void configure(Type type, Properties params, Dialect d) throws MappingException { entityName = params.getProperty(ENTITY_NAME); - if (entityName==null) { + if ( entityName == null ) { throw new MappingException("no entity name"); } } diff --git a/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java b/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java index 0a02779b5e..9a04e82ebd 100755 --- a/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java +++ b/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java @@ -129,7 +129,7 @@ public class StatelessSessionImpl extends AbstractSessionImpl public void delete(String entityName, Object entity) { errorIfClosed(); 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); persister.delete(id, version, entity, this); } @@ -145,7 +145,7 @@ public class StatelessSessionImpl extends AbstractSessionImpl public void update(String entityName, Object entity) { errorIfClosed(); 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 oldVersion; if ( persister.isVersioned() ) { @@ -197,7 +197,7 @@ public class StatelessSessionImpl extends AbstractSessionImpl public void refresh(String entityName, Object entity, LockMode lockMode) { final EntityPersister persister = this.getEntityPersister( entityName, entity ); - final Serializable id = persister.getIdentifier( entity, getEntityMode() ); + final Serializable id = persister.getIdentifier( entity, this ); if ( log.isTraceEnabled() ) { log.trace( "refreshing transient " + diff --git a/core/src/main/java/org/hibernate/mapping/Component.java b/core/src/main/java/org/hibernate/mapping/Component.java index 65d61db019..b36862c57a 100644 --- a/core/src/main/java/org/hibernate/mapping/Component.java +++ b/core/src/main/java/org/hibernate/mapping/Component.java @@ -419,8 +419,7 @@ public class Component extends SimpleValue implements MetaAttributable { } public Serializable locateGenerationContext(SessionImplementor session, Object incomingObject) { - return session.getEntityPersister( entityName, incomingObject ) - .getIdentifier( incomingObject, session.getEntityMode() ); + return session.getEntityPersister( entityName, incomingObject ).getIdentifier( incomingObject, session ); } } diff --git a/core/src/main/java/org/hibernate/metadata/ClassMetadata.java b/core/src/main/java/org/hibernate/metadata/ClassMetadata.java index ac5068a4cf..17403b9f33 100644 --- a/core/src/main/java/org/hibernate/metadata/ClassMetadata.java +++ b/core/src/main/java/org/hibernate/metadata/ClassMetadata.java @@ -195,8 +195,20 @@ public interface ClassMetadata { /** * 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. diff --git a/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 5283a703e7..86d604960d 100644 --- a/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -3514,7 +3514,7 @@ public abstract class AbstractEntityPersister public Boolean isTransient(Object entity, SessionImplementor session) throws HibernateException { final Serializable id; if ( canExtractIdOutOfEntity() ) { - id = getIdentifier( entity, session.getEntityMode() ); + id = getIdentifier( entity, session ); } else { id = null; @@ -3796,9 +3796,12 @@ public abstract class AbstractEntityPersister return getTuplizer( entityMode ).getPropertyValue( object, propertyName ); } - public Serializable getIdentifier(Object object, EntityMode entityMode) - throws HibernateException { - return getTuplizer( entityMode ).getIdentifier( object ); + public Serializable getIdentifier(Object object, EntityMode entityMode) throws HibernateException { + return getTuplizer( entityMode ).getIdentifier( object, null ); + } + + public Serializable getIdentifier(Object entity, SessionImplementor session) { + return getTuplizer( session.getEntityMode() ).getIdentifier( entity, session ); } /** diff --git a/core/src/main/java/org/hibernate/persister/entity/EntityPersister.java b/core/src/main/java/org/hibernate/persister/entity/EntityPersister.java index dd1fa643a2..fe85a6a730 100644 --- a/core/src/main/java/org/hibernate/persister/entity/EntityPersister.java +++ b/core/src/main/java/org/hibernate/persister/entity/EntityPersister.java @@ -652,9 +652,21 @@ public interface EntityPersister extends OptimisticCacheSource { /** * 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; + /** + * 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. *

diff --git a/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java b/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java index 9a4bc87dae..cc65a6e1f3 100644 --- a/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java +++ b/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java @@ -28,12 +28,20 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.hibernate.EntityMode; import org.hibernate.HibernateException; import org.hibernate.MappingException; +import org.hibernate.engine.Cascade; +import org.hibernate.engine.EntityEntry; import org.hibernate.engine.EntityKey; import org.hibernate.engine.SessionFactoryImplementor; 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.intercept.LazyPropertyInitializer; import org.hibernate.mapping.Component; @@ -42,6 +50,7 @@ import org.hibernate.mapping.Property; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.property.Getter; import org.hibernate.property.Setter; +import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.ProxyFactory; import org.hibernate.tuple.Instantiator; import org.hibernate.tuple.StandardProperty; @@ -60,6 +69,8 @@ import org.hibernate.type.Type; */ 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! private final EntityMetamodel entityMetamodel; @@ -198,6 +209,10 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer { } public Serializable getIdentifier(Object entity) throws HibernateException { + return getIdentifier( entity, null ); + } + + public Serializable getIdentifier(Object entity, SessionImplementor session) { final Object id; if ( entityMetamodel.getIdentifierProperty().isEmbedded() ) { id = entity; @@ -208,7 +223,7 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer { throw new HibernateException( "The class has no identifier property: " + getEntityName() ); } else { - id = mappedIdentifierValueMarshaller.getIdentifier( entity, getEntityMode(), getFactory() ); + id = mappedIdentifierValueMarshaller.getIdentifier( entity, getEntityMode(), session ); } } else { @@ -255,13 +270,13 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer { idSetter.set( entity, id, getFactory() ); } else if ( identifierMapperType != null ) { - mappedIdentifierValueMarshaller.setIdentifier( entity, id, session ); + mappedIdentifierValueMarshaller.setIdentifier( entity, id, getEntityMode(), session ); } } private static interface MappedIdentifierValueMarshaller { - public Object getIdentifier(Object entity, EntityMode entityMode, SessionFactoryImplementor factory); - public void setIdentifier(Object entity, Serializable id, SessionImplementor session); + public Object getIdentifier(Object entity, EntityMode entityMode, SessionImplementor session); + public void setIdentifier(Object entity, Serializable id, EntityMode entityMode, SessionImplementor session); } private final MappedIdentifierValueMarshaller mappedIdentifierValueMarshaller; @@ -304,18 +319,18 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer { 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[] propertyValues = virtualIdComponent.getPropertyValues( entity, entityMode ); mappedIdentifierType.setPropertyValues( id, propertyValues, entityMode ); return id; } - public void setIdentifier(Object entity, Serializable id, SessionImplementor session) { + public void setIdentifier(Object entity, Serializable id, EntityMode entityMode, SessionImplementor session) { virtualIdComponent.setPropertyValues( entity, mappedIdentifierType.getPropertyValues( id, session ), - session.getEntityMode() + entityMode ); } } @@ -329,47 +344,79 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer { this.mappedIdentifierType = mappedIdentifierType; } - public Object getIdentifier(Object entity, EntityMode entityMode, SessionFactoryImplementor factory) { - Object id = mappedIdentifierType.instantiate( entityMode ); + public Object getIdentifier(Object entity, EntityMode entityMode, SessionImplementor session) { + final Object id = mappedIdentifierType.instantiate( entityMode ); final Object[] propertyValues = virtualIdComponent.getPropertyValues( entity, entityMode ); - Type[] subTypes = virtualIdComponent.getSubtypes(); - Type[] copierSubTypes = mappedIdentifierType.getSubtypes(); + final Type[] subTypes = virtualIdComponent.getSubtypes(); + final Type[] copierSubTypes = mappedIdentifierType.getSubtypes(); final int length = subTypes.length; for ( int i = 0 ; i < length; i++ ) { 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() ) { - final String associatedEntityName = ( ( EntityType ) subTypes[i] ).getAssociatedEntityName(); - final EntityPersister entityPersister = factory.getEntityPersister( associatedEntityName ); - propertyValues[i] = entityPersister.getIdentifier( propertyValues[i], entityMode ); + // we need a session to handle this use case + if ( session == null ) { + 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 ); return id; } - public void setIdentifier(Object entity, Serializable id, SessionImplementor session) { - final Object[] extractedValues = mappedIdentifierType.getPropertyValues( id, session.getEntityMode() ); + public void setIdentifier(Object entity, Serializable id, EntityMode entityMode, SessionImplementor session) { + final Object[] extractedValues = mappedIdentifierType.getPropertyValues( id, entityMode ); final Object[] injectionValues = new Object[ extractedValues.length ]; for ( int i = 0; i < virtualIdComponent.getSubtypes().length; i++ ) { final Type virtualPropertyType = virtualIdComponent.getSubtypes()[i]; final Type idClassPropertyType = mappedIdentifierType.getSubtypes()[i]; 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 EntityKey entityKey = new EntityKey( (Serializable) extractedValues[i], session.getFactory().getEntityPersister( associatedEntityName ), - session.getEntityMode() + entityMode ); // it is conceivable there is a proxy, so check that first - Object association = session.getPersistenceContext() - .getProxy( entityKey ); + Object association = session.getPersistenceContext().getProxy( entityKey ); if ( association == null ) { // otherwise look for an initialized version - association = session.getPersistenceContext() - .getEntity( entityKey ); + association = session.getPersistenceContext().getEntity( entityKey ); } injectionValues[i] = association; } diff --git a/core/src/main/java/org/hibernate/tuple/entity/Dom4jEntityTuplizer.java b/core/src/main/java/org/hibernate/tuple/entity/Dom4jEntityTuplizer.java index a1948b8e5d..38d1d70fed 100644 --- a/core/src/main/java/org/hibernate/tuple/entity/Dom4jEntityTuplizer.java +++ b/core/src/main/java/org/hibernate/tuple/entity/Dom4jEntityTuplizer.java @@ -24,6 +24,7 @@ */ package org.hibernate.tuple.entity; +import org.hibernate.engine.SessionImplementor; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.proxy.ProxyFactory; @@ -117,15 +118,22 @@ public class Dom4jEntityTuplizer extends AbstractEntityTuplizer { * {@inheritDoc} */ public Serializable getIdentifier(Object entityOrId) throws HibernateException { - if (entityOrId instanceof Element) { - return super.getIdentifier(entityOrId); + return getIdentifier( entityOrId, null ); + } + + /** + * {@inheritDoc} + */ + public Serializable getIdentifier(Object entityOrId, SessionImplementor session) { + if ( entityOrId instanceof Element ) { + return super.getIdentifier( entityOrId, session ); } else { //it was not embedded, so the argument is just an id return (Serializable) entityOrId; } } - + /** * {@inheritDoc} */ diff --git a/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java b/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java index 57872eedd9..ee775ba30d 100644 --- a/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java +++ b/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java @@ -79,12 +79,26 @@ public interface EntityTuplizer extends Tuplizer { * Extract the identifier value from the given entity. * * @param entity The entity from which to extract the identifier value. + * * @return The identifier value. + * * @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; + /** + * 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. *

diff --git a/core/src/main/java/org/hibernate/type/CollectionType.java b/core/src/main/java/org/hibernate/type/CollectionType.java index b6887c3347..db5a28da49 100644 --- a/core/src/main/java/org/hibernate/type/CollectionType.java +++ b/core/src/main/java/org/hibernate/type/CollectionType.java @@ -403,7 +403,7 @@ public abstract class CollectionType extends AbstractType implements Association if ( ownerMappedClass.isAssignableFrom( keyType.getReturnedClass() ) && keyType.getReturnedClass().isInstance( 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 { // TODO: check if key contains the owner ID diff --git a/entitymanager/src/main/java/org/hibernate/ejb/event/EJB3DeleteEventListener.java b/entitymanager/src/main/java/org/hibernate/ejb/event/EJB3DeleteEventListener.java index 8b3137ba55..4c57ebdde5 100644 --- a/entitymanager/src/main/java/org/hibernate/ejb/event/EJB3DeleteEventListener.java +++ b/entitymanager/src/main/java/org/hibernate/ejb/event/EJB3DeleteEventListener.java @@ -60,7 +60,7 @@ public class EJB3DeleteEventListener extends DefaultDeleteEventListener implemen EventSource source = event.getSession(); String entityName = event.getEntityName(); 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; throw new IllegalArgumentException("Removing a detached instance "+ entityName + "#" + id); } diff --git a/envers/src/main/java/org/hibernate/envers/tools/Tools.java b/envers/src/main/java/org/hibernate/envers/tools/Tools.java index 7e4178f30c..a699ae36d2 100644 --- a/envers/src/main/java/org/hibernate/envers/tools/Tools.java +++ b/envers/src/main/java/org/hibernate/envers/tools/Tools.java @@ -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) { diff --git a/testsuite/src/test/java/org/hibernate/test/legacy/CustomPersister.java b/testsuite/src/test/java/org/hibernate/test/legacy/CustomPersister.java index d139289a9a..e8013c7497 100644 --- a/testsuite/src/test/java/org/hibernate/test/legacy/CustomPersister.java +++ b/testsuite/src/test/java/org/hibernate/test/legacy/CustomPersister.java @@ -182,6 +182,11 @@ public class CustomPersister implements EntityPersister { 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 { checkEntityMode( entityMode ); ( (Custom) object ).id = (String) id;