HHH-14424 When enhanced as a proxy is enabled with dirty checking, on flush uninitialized entities containing collections are updated and all the fields are set to null
This commit is contained in:
parent
26a46b2010
commit
cfc7b97250
|
@ -35,6 +35,7 @@ public class EnhancementAsProxyLazinessInterceptor extends AbstractLazyLoadInter
|
||||||
|
|
||||||
private final boolean inLineDirtyChecking;
|
private final boolean inLineDirtyChecking;
|
||||||
private Set<String> writtenFieldNames;
|
private Set<String> writtenFieldNames;
|
||||||
|
private Set<String> collectionAttributeNames;
|
||||||
|
|
||||||
private Status status;
|
private Status status;
|
||||||
|
|
||||||
|
@ -57,11 +58,22 @@ public class EnhancementAsProxyLazinessInterceptor extends AbstractLazyLoadInter
|
||||||
this.entityKey = entityKey;
|
this.entityKey = entityKey;
|
||||||
|
|
||||||
final EntityPersister entityPersister = session.getFactory().getMetamodel().entityPersister( entityName );
|
final EntityPersister entityPersister = session.getFactory().getMetamodel().entityPersister( entityName );
|
||||||
|
if ( entityPersister.hasCollections() ) {
|
||||||
|
Type[] propertyTypes = entityPersister.getPropertyTypes();
|
||||||
|
collectionAttributeNames = new HashSet<>();
|
||||||
|
for ( int i = 0; i < propertyTypes.length; i++ ) {
|
||||||
|
Type propertyType = propertyTypes[i];
|
||||||
|
if ( propertyType.isCollectionType() ) {
|
||||||
|
collectionAttributeNames.add( entityPersister.getPropertyNames()[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.inLineDirtyChecking = entityPersister.getEntityMode() == EntityMode.POJO
|
this.inLineDirtyChecking = entityPersister.getEntityMode() == EntityMode.POJO
|
||||||
&& SelfDirtinessTracker.class.isAssignableFrom( entityPersister.getMappedClass() );
|
&& SelfDirtinessTracker.class.isAssignableFrom( entityPersister.getMappedClass() );
|
||||||
// if self-dirty tracking is enabled but DynamicUpdate is not enabled then we need to initialise the entity
|
// if self-dirty tracking is enabled but DynamicUpdate is not enabled then we need to initialise the entity
|
||||||
// because the pre-computed update statement contains even not dirty properties and so we need all the values
|
// because the pre-computed update statement contains even not dirty properties and so we need all the values
|
||||||
initializeBeforeWrite = !inLineDirtyChecking || !entityPersister.getEntityMetamodel().isDynamicUpdate();
|
initializeBeforeWrite = !( inLineDirtyChecking && entityPersister.getEntityMetamodel().isDynamicUpdate() );
|
||||||
status = Status.UNINITIALIZED;
|
status = Status.UNINITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +257,8 @@ public class EnhancementAsProxyLazinessInterceptor extends AbstractLazyLoadInter
|
||||||
return newValue;
|
return newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( initializeBeforeWrite ) {
|
if ( initializeBeforeWrite
|
||||||
|
|| ( collectionAttributeNames != null && collectionAttributeNames.contains( attributeName ) ) ) {
|
||||||
// we need to force-initialize the proxy - the fetch group to which the `attributeName` belongs
|
// we need to force-initialize the proxy - the fetch group to which the `attributeName` belongs
|
||||||
try {
|
try {
|
||||||
forceInitialize( target, attributeName );
|
forceInitialize( target, attributeName );
|
||||||
|
@ -267,6 +280,8 @@ public class EnhancementAsProxyLazinessInterceptor extends AbstractLazyLoadInter
|
||||||
writtenFieldNames = new HashSet<>();
|
writtenFieldNames = new HashSet<>();
|
||||||
}
|
}
|
||||||
writtenFieldNames.add( attributeName );
|
writtenFieldNames.add( attributeName );
|
||||||
|
|
||||||
|
( (SelfDirtinessTracker) target ).$$_hibernate_trackChange( attributeName );
|
||||||
}
|
}
|
||||||
|
|
||||||
return newValue;
|
return newValue;
|
||||||
|
@ -323,6 +338,10 @@ public class EnhancementAsProxyLazinessInterceptor extends AbstractLazyLoadInter
|
||||||
status = Status.INITIALIZED;
|
status = Status.INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasWrittenFieldNames() {
|
||||||
|
return writtenFieldNames != null && writtenFieldNames.size() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
private enum Status {
|
private enum Status {
|
||||||
UNINITIALIZED,
|
UNINITIALIZED,
|
||||||
INITIALIZING,
|
INITIALIZING,
|
||||||
|
|
|
@ -9,7 +9,6 @@ package org.hibernate.engine.internal;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.CustomEntityDirtinessStrategy;
|
import org.hibernate.CustomEntityDirtinessStrategy;
|
||||||
|
@ -353,8 +352,12 @@ public abstract class AbstractEntityEntry implements Serializable, EntityEntry {
|
||||||
final PersistentAttributeInterceptor interceptor = interceptable.$$_hibernate_getInterceptor();
|
final PersistentAttributeInterceptor interceptor = interceptable.$$_hibernate_getInterceptor();
|
||||||
if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor ) {
|
if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor ) {
|
||||||
EnhancementAsProxyLazinessInterceptor enhancementAsProxyLazinessInterceptor = (EnhancementAsProxyLazinessInterceptor) interceptor;
|
EnhancementAsProxyLazinessInterceptor enhancementAsProxyLazinessInterceptor = (EnhancementAsProxyLazinessInterceptor) interceptor;
|
||||||
|
if ( enhancementAsProxyLazinessInterceptor.hasWrittenFieldNames() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// When a proxy has dirty attributes, we have to treat it like a normal entity to flush changes
|
// When a proxy has dirty attributes, we have to treat it like a normal entity to flush changes
|
||||||
uninitializedProxy = !enhancementAsProxyLazinessInterceptor.isInitialized() && !( (SelfDirtinessTracker) entity ).$$_hibernate_hasDirtyAttributes();
|
return !enhancementAsProxyLazinessInterceptor.isInitialized()
|
||||||
|
|| !persister.hasCollections() && !( (SelfDirtinessTracker) entity ).$$_hibernate_hasDirtyAttributes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( entity instanceof HibernateProxy ) {
|
else if ( entity instanceof HibernateProxy ) {
|
||||||
|
|
Loading…
Reference in New Issue