HHH-13607 - Exception thrown while flushing uninitialized enhanced proxy with immutable natural ID
(cherry picked from commit 7ceaf3aaa4
)
This commit is contained in:
parent
c3286a2b56
commit
5274f15ef5
|
@ -17,10 +17,13 @@ import org.hibernate.StaleObjectStateException;
|
||||||
import org.hibernate.action.internal.DelayedPostInsertIdentifier;
|
import org.hibernate.action.internal.DelayedPostInsertIdentifier;
|
||||||
import org.hibernate.action.internal.EntityUpdateAction;
|
import org.hibernate.action.internal.EntityUpdateAction;
|
||||||
import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer;
|
import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer;
|
||||||
|
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor;
|
||||||
import org.hibernate.engine.internal.Nullability;
|
import org.hibernate.engine.internal.Nullability;
|
||||||
import org.hibernate.engine.internal.Versioning;
|
import org.hibernate.engine.internal.Versioning;
|
||||||
import org.hibernate.engine.spi.EntityEntry;
|
import org.hibernate.engine.spi.EntityEntry;
|
||||||
import org.hibernate.engine.spi.EntityKey;
|
import org.hibernate.engine.spi.EntityKey;
|
||||||
|
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
|
||||||
|
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
|
||||||
import org.hibernate.engine.spi.SelfDirtinessTracker;
|
import org.hibernate.engine.spi.SelfDirtinessTracker;
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.engine.spi.Status;
|
import org.hibernate.engine.spi.Status;
|
||||||
|
@ -82,14 +85,24 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
||||||
|
|
||||||
private void checkNaturalId(
|
private void checkNaturalId(
|
||||||
EntityPersister persister,
|
EntityPersister persister,
|
||||||
|
Object entity,
|
||||||
EntityEntry entry,
|
EntityEntry entry,
|
||||||
Object[] current,
|
Object[] current,
|
||||||
Object[] loaded,
|
Object[] loaded,
|
||||||
SessionImplementor session) {
|
SessionImplementor session) {
|
||||||
|
if ( entity instanceof PersistentAttributeInterceptable ) {
|
||||||
|
final PersistentAttributeInterceptor interceptor = ( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor();
|
||||||
|
if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor ) {
|
||||||
|
// EARLY EXIT!!!
|
||||||
|
// nothing to check - the entity is an un-initialized enhancement-as-proxy reference
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( persister.hasNaturalIdentifier() && entry.getStatus() != Status.READ_ONLY ) {
|
if ( persister.hasNaturalIdentifier() && entry.getStatus() != Status.READ_ONLY ) {
|
||||||
if ( !persister.getEntityMetamodel().hasImmutableNaturalId() ) {
|
if ( !persister.getEntityMetamodel().hasImmutableNaturalId() ) {
|
||||||
// SHORT-CUT: if the natural id is mutable (!immutable), no need to do the below checks
|
|
||||||
// EARLY EXIT!!!
|
// EARLY EXIT!!!
|
||||||
|
// the natural id is mutable (!immutable), no need to do the below checks
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +125,7 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
||||||
if ( !propertyType.isEqual( current[naturalIdentifierPropertyIndex], snapshot[i] ) ) {
|
if ( !propertyType.isEqual( current[naturalIdentifierPropertyIndex], snapshot[i] ) ) {
|
||||||
throw new HibernateException(
|
throw new HibernateException(
|
||||||
String.format(
|
String.format(
|
||||||
"An immutable natural identifier of entity %s was altered from %s to %s",
|
"An immutable natural identifier of entity %s was altered from `%s` to `%s`",
|
||||||
persister.getEntityName(),
|
persister.getEntityName(),
|
||||||
propertyTypes[naturalIdentifierPropertyIndex].toLoggableString(
|
propertyTypes[naturalIdentifierPropertyIndex].toLoggableString(
|
||||||
snapshot[i],
|
snapshot[i],
|
||||||
|
@ -188,7 +201,7 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
||||||
// grab its current state
|
// grab its current state
|
||||||
values = persister.getPropertyValues( entity );
|
values = persister.getPropertyValues( entity );
|
||||||
|
|
||||||
checkNaturalId( persister, entry, values, loadedState, session );
|
checkNaturalId( persister, entity, entry, values, loadedState, session );
|
||||||
}
|
}
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue