diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultFlushEntityEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultFlushEntityEventListener.java index e3bb6f29c7bb..1a2005300a17 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultFlushEntityEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultFlushEntityEventListener.java @@ -70,28 +70,26 @@ public void injectCallbackRegistry(CallbackRegistry callbackRegistry) { /** * Make sure user didn't mangle the id. */ - public void checkId(Object object, EntityPersister persister, Object id, Status status, SessionImplementor session) + public void checkId(Object object, EntityPersister persister, EntityEntry entry, SessionImplementor session) throws HibernateException { - - if ( id instanceof DelayedPostInsertIdentifier ) { - // this is a situation where the entity id is assigned by a post-insert generator - // and was saved outside the transaction forcing it to be delayed - return; - } - - final Object 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)" ); - } - // Small optimisation: always try to avoid getIdentifierType().isEqual(..) when possible. - // (However it's not safe to invoke the equals() method as it might trigger side effects.) - else if ( id != oid - && !status.isDeletedOrGone() - && !persister.getIdentifierType().isEqual( id, oid, session.getFactory() ) ) { - throw new HibernateException( "identifier of an instance of " + persister.getEntityName() - + " was altered from " + oid + " to " + id ); + final Object entryId = entry.getId(); + if ( entryId == null ) { + throw new AssertionFailure( "Entry for instance of '" + persister.getEntityName() + + "' has a null identifier (this can happen if the session is flushed after an exception occurs)" ); + } + if ( !(entryId instanceof DelayedPostInsertIdentifier) ) { + final Object currentId = persister.getIdentifier( object, session ); + // Small optimisation: always try to avoid getIdentifierType().isEqual(..) when possible. + // (However it's not safe to invoke the equals() method as it might trigger side effects.) + if ( entryId != currentId + && !entry.getStatus().isDeletedOrGone() + && !persister.getIdentifierType().isEqual( entryId, currentId, session.getFactory() ) ) { + throw new HibernateException( "Identifier of an instance of '" + persister.getEntityName() + + "' was altered from " + entryId + " to " + currentId ); + } } + // else this is a situation where the entity id is assigned by a post-insert + // generator and was saved outside the transaction, forcing it to be delayed } private void checkNaturalId( @@ -174,7 +172,7 @@ private Object[] getValues(Object entity, EntityEntry entry, boolean mightBeDirt } else { final EntityPersister persister = entry.getPersister(); - checkId( entity, persister, entry.getId(), entry.getStatus(), session ); + checkId( entity, persister, entry, session ); // grab its current state final Object[] values = persister.getValues( entity ); checkNaturalId( persister, entity, entry, values, loadedState, session );