HHH-18713 saveOrUpdate changed behaviour with bytecode enhancer
This commit is contained in:
parent
b26441aee8
commit
cef03a3256
|
@ -10,6 +10,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor;
|
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor;
|
||||||
|
@ -19,6 +20,7 @@ import org.hibernate.engine.spi.CascadingAction;
|
||||||
import org.hibernate.engine.spi.CollectionEntry;
|
import org.hibernate.engine.spi.CollectionEntry;
|
||||||
import org.hibernate.engine.spi.EntityEntry;
|
import org.hibernate.engine.spi.EntityEntry;
|
||||||
import org.hibernate.engine.spi.PersistenceContext;
|
import org.hibernate.engine.spi.PersistenceContext;
|
||||||
|
import org.hibernate.engine.spi.SelfDirtinessTracker;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.engine.spi.Status;
|
import org.hibernate.engine.spi.Status;
|
||||||
import org.hibernate.event.spi.DeleteContext;
|
import org.hibernate.event.spi.DeleteContext;
|
||||||
|
@ -27,8 +29,6 @@ import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.pretty.MessageHelper;
|
|
||||||
import org.hibernate.proxy.HibernateProxy;
|
|
||||||
import org.hibernate.type.AnyType;
|
import org.hibernate.type.AnyType;
|
||||||
import org.hibernate.type.AssociationType;
|
import org.hibernate.type.AssociationType;
|
||||||
import org.hibernate.type.CollectionType;
|
import org.hibernate.type.CollectionType;
|
||||||
|
@ -38,13 +38,13 @@ import org.hibernate.type.EntityType;
|
||||||
import org.hibernate.type.ForeignKeyDirection;
|
import org.hibernate.type.ForeignKeyDirection;
|
||||||
import org.hibernate.type.ManyToOneType;
|
import org.hibernate.type.ManyToOneType;
|
||||||
import org.hibernate.type.OneToOneType;
|
import org.hibernate.type.OneToOneType;
|
||||||
import org.hibernate.type.OneToOneType;
|
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
import static org.hibernate.engine.internal.ManagedTypeHelper.asManagedEntity;
|
||||||
|
import static org.hibernate.engine.internal.ManagedTypeHelper.asSelfDirtinessTrackerOrNull;
|
||||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy;
|
import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy;
|
||||||
import static org.hibernate.engine.spi.CascadingActions.CHECK_ON_FLUSH;
|
import static org.hibernate.engine.spi.CascadingActions.CHECK_ON_FLUSH;
|
||||||
import static org.hibernate.pretty.MessageHelper.infoString;
|
import static org.hibernate.pretty.MessageHelper.infoString;
|
||||||
import static org.hibernate.type.ForeignKeyDirection.TO_PARENT;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delegate responsible for, in conjunction with the various
|
* Delegate responsible for, in conjunction with the various
|
||||||
|
@ -97,15 +97,29 @@ public final class Cascade {
|
||||||
final PersistenceContext persistenceContext = eventSource.getPersistenceContextInternal();
|
final PersistenceContext persistenceContext = eventSource.getPersistenceContextInternal();
|
||||||
final boolean enhancedForLazyLoading = persister.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading();
|
final boolean enhancedForLazyLoading = persister.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading();
|
||||||
final EntityEntry entry;
|
final EntityEntry entry;
|
||||||
|
final Set<String> dirtyAttributes;
|
||||||
if ( enhancedForLazyLoading ) {
|
if ( enhancedForLazyLoading ) {
|
||||||
entry = persistenceContext.getEntry( parent );
|
entry = persistenceContext.getEntry( parent );
|
||||||
if ( entry != null
|
if ( entry != null && entry.getLoadedState() == null && entry.getStatus() == Status.MANAGED ) {
|
||||||
&& entry.getLoadedState() == null
|
final SelfDirtinessTracker selfDirtinessTracker = asSelfDirtinessTrackerOrNull( parent );
|
||||||
&& entry.getStatus() == Status.MANAGED ) {
|
if ( selfDirtinessTracker == null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if ( asManagedEntity( parent ).$$_hibernate_useTracker() ) {
|
||||||
|
dirtyAttributes = Set.of( selfDirtinessTracker.$$_hibernate_getDirtyAttributes() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dirtyAttributes = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
dirtyAttributes = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dirtyAttributes = null;
|
||||||
entry = null;
|
entry = null;
|
||||||
}
|
}
|
||||||
final Type[] types = persister.getPropertyTypes();
|
final Type[] types = persister.getPropertyTypes();
|
||||||
|
@ -114,8 +128,11 @@ public final class Cascade {
|
||||||
final boolean hasUninitializedLazyProperties = persister.hasUninitializedLazyProperties( parent );
|
final boolean hasUninitializedLazyProperties = persister.hasUninitializedLazyProperties( parent );
|
||||||
|
|
||||||
for ( int i = 0; i < types.length; i++) {
|
for ( int i = 0; i < types.length; i++) {
|
||||||
final CascadeStyle style = cascadeStyles[ i ];
|
|
||||||
final String propertyName = propertyNames[ i ];
|
final String propertyName = propertyNames[ i ];
|
||||||
|
if ( dirtyAttributes != null && !dirtyAttributes.contains( propertyName ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final CascadeStyle style = cascadeStyles[ i ];
|
||||||
final Type type = types[i];
|
final Type type = types[i];
|
||||||
final boolean isUninitializedProperty =
|
final boolean isUninitializedProperty =
|
||||||
hasUninitializedLazyProperties &&
|
hasUninitializedLazyProperties &&
|
||||||
|
|
|
@ -390,6 +390,15 @@ public final class ManagedTypeHelper {
|
||||||
throw new ClassCastException( "Object of type '" + entity.getClass() + "' can't be cast to SelfDirtinessTracker" );
|
throw new ClassCastException( "Object of type '" + entity.getClass() + "' can't be cast to SelfDirtinessTracker" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SelfDirtinessTracker asSelfDirtinessTrackerOrNull(final Object entity) {
|
||||||
|
Objects.requireNonNull( entity );
|
||||||
|
if ( entity instanceof PrimeAmongSecondarySupertypes ) {
|
||||||
|
PrimeAmongSecondarySupertypes t = (PrimeAmongSecondarySupertypes) entity;
|
||||||
|
return t.asSelfDirtinessTracker();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast the object to an HibernateProxy, or return null in case it is not an instance of HibernateProxy
|
* Cast the object to an HibernateProxy, or return null in case it is not an instance of HibernateProxy
|
||||||
* @param entity the entity to cast
|
* @param entity the entity to cast
|
||||||
|
|
Loading…
Reference in New Issue