HHH-14549 Collection with default field initializer will always be empty

This commit is contained in:
Andrea Boriero 2021-04-12 18:03:35 +02:00 committed by Yoann Rodière
parent 0a8a8091b4
commit 56e9769741
3 changed files with 24 additions and 11 deletions

View File

@ -22,7 +22,6 @@ 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.ManagedEntity;
import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.PersistentAttributeInterceptable; import org.hibernate.engine.spi.PersistentAttributeInterceptable;
import org.hibernate.engine.spi.PersistentAttributeInterceptor; import org.hibernate.engine.spi.PersistentAttributeInterceptor;
@ -40,7 +39,6 @@ import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
import org.hibernate.metadata.ClassMetadata; import org.hibernate.metadata.ClassMetadata;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.pretty.MessageHelper; import org.hibernate.pretty.MessageHelper;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.stat.spi.StatisticsImplementor; import org.hibernate.stat.spi.StatisticsImplementor;
import org.hibernate.type.Type; import org.hibernate.type.Type;
@ -166,7 +164,8 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
event.setPropertyValues( values ); event.setPropertyValues( values );
//TODO: avoid this for non-new instances where mightBeDirty==false //TODO: avoid this for non-new instances where mightBeDirty==false
boolean substitute = wrapCollections( session, persister, types, values );
boolean substitute = wrapCollections( session, persister, entity, entry.getId(), types, values );
if ( isUpdateNecessary( event, mightBeDirty ) ) { if ( isUpdateNecessary( event, mightBeDirty ) ) {
substitute = scheduleUpdate( event ) || substitute; substitute = scheduleUpdate( event ) || substitute;
@ -214,6 +213,8 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
private boolean wrapCollections( private boolean wrapCollections(
EventSource session, EventSource session,
EntityPersister persister, EntityPersister persister,
Object entity,
Serializable id,
Type[] types, Type[] types,
Object[] values Object[] values
) { ) {
@ -227,7 +228,7 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
// don't dirty the container. Also, for versioned data, we // don't dirty the container. Also, for versioned data, we
// need to wrap before calling searchForDirtyCollections // need to wrap before calling searchForDirtyCollections
WrapVisitor visitor = new WrapVisitor( session ); WrapVisitor visitor = new WrapVisitor( entity, id ,session );
// substitutes into values by side-effect // substitutes into values by side-effect
visitor.processEntityPropertyValues( values, types ); visitor.processEntityPropertyValues( values, types );
return visitor.isSubstitutionRequired(); return visitor.isSubstitutionRequired();

View File

@ -43,9 +43,12 @@ public class FlushVisitor extends AbstractVisitor {
else if ( collection == LazyPropertyInitializer.UNFETCHED_PROPERTY ) { else if ( collection == LazyPropertyInitializer.UNFETCHED_PROPERTY ) {
coll = (PersistentCollection) type.resolve( collection, session, owner ); coll = (PersistentCollection) type.resolve( collection, session, owner );
} }
else { else if ( collection instanceof PersistentCollection ) {
coll = (PersistentCollection) collection; coll = (PersistentCollection) collection;
} }
else {
return null;
}
Collections.processReachableCollection( coll, type, owner, session); Collections.processReachableCollection( coll, type, owner, session);
} }

View File

@ -11,8 +11,11 @@ import java.io.Serializable;
import org.hibernate.EntityMode; import org.hibernate.EntityMode;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
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.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.event.spi.EventSource; import org.hibernate.event.spi.EventSource;
import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreLogging;
@ -31,8 +34,8 @@ import org.hibernate.type.Type;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
public class WrapVisitor extends ProxyVisitor { public class WrapVisitor extends ProxyVisitor {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( WrapVisitor.class ); private static final CoreMessageLogger LOG = CoreLogging.messageLogger( WrapVisitor.class );
private Object entity; protected Object entity;
private Serializable id; protected Serializable id;
private boolean substitute; private boolean substitute;
@ -105,8 +108,17 @@ public class WrapVisitor extends ProxyVisitor {
return null; return null;
} }
else { else {
if ( entity instanceof PersistentAttributeInterceptable ) {
final PersistentAttributeInterceptor interceptor = ( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor();
if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor ) {
if ( !( (EnhancementAsProxyLazinessInterceptor) interceptor ).isInitialized() ) {
return null;
}
}
}
final PersistentCollection persistentCollection = collectionType.wrap( session, collection );
PersistentCollection persistentCollection = collectionType.wrap( session, collection );
persistenceContext.addNewCollection( persister, persistentCollection ); persistenceContext.addNewCollection( persister, persistentCollection );
if ( LOG.isTraceEnabled() ) { if ( LOG.isTraceEnabled() ) {
@ -114,11 +126,8 @@ public class WrapVisitor extends ProxyVisitor {
} }
return persistentCollection; //Force a substitution! return persistentCollection; //Force a substitution!
} }
} }
} }
@Override @Override