From 940259dc4c1eeb25ced02b342e6c28f23e01a95e Mon Sep 17 00:00:00 2001 From: Christian Beikov Date: Tue, 27 Jun 2023 12:41:41 +0200 Subject: [PATCH] HHH-14176 Handle embedded composite ids in envers specially to avoid lazy loading --- .../entities/mapper/id/MultipleIdMapper.java | 22 +++++++++++++++++-- .../mapper/relation/ToOneIdMapper.java | 16 -------------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/MultipleIdMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/MultipleIdMapper.java index edf11ae9f6..86cb71e451 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/MultipleIdMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/MultipleIdMapper.java @@ -14,6 +14,8 @@ import java.util.Map; import org.hibernate.Session; import org.hibernate.envers.internal.entities.PropertyData; import org.hibernate.mapping.Component; +import org.hibernate.proxy.HibernateProxy; +import org.hibernate.proxy.LazyInitializer; import org.hibernate.service.ServiceRegistry; /** @@ -25,12 +27,16 @@ import org.hibernate.service.ServiceRegistry; */ public class MultipleIdMapper extends AbstractCompositeIdMapper implements SimpleIdMapperBuilder { + private final boolean embedded; + public MultipleIdMapper(Component component) { super( component.getComponentClass(), component.getServiceRegistry() ); + this.embedded = component.isEmbedded(); } - private MultipleIdMapper(Class compositeIdClass, ServiceRegistry serviceRegistry) { + private MultipleIdMapper(boolean embedded, Class compositeIdClass, ServiceRegistry serviceRegistry) { super( compositeIdClass, serviceRegistry ); + this.embedded = embedded; } @Override @@ -41,6 +47,12 @@ public class MultipleIdMapper extends AbstractCompositeIdMapper implements Simpl @Override public void mapToMapFromId(Session session, Map data, Object obj) { if ( compositeIdClass.isInstance( obj ) ) { + if ( embedded ) { + final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( obj ); + if ( lazyInitializer != null ) { + obj = lazyInitializer.getInternalIdentifier(); + } + } for ( Map.Entry entry : ids.entrySet() ) { final PropertyData propertyData = entry.getKey(); final AbstractIdMapper idMapper = entry.getValue(); @@ -67,6 +79,12 @@ public class MultipleIdMapper extends AbstractCompositeIdMapper implements Simpl @Override public void mapToMapFromEntity(Map data, Object obj) { + if ( embedded ) { + final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( obj ); + if ( lazyInitializer != null ) { + obj = lazyInitializer.getInternalIdentifier(); + } + } for ( IdMapper idMapper : ids.values() ) { idMapper.mapToMapFromEntity( data, obj ); } @@ -84,7 +102,7 @@ public class MultipleIdMapper extends AbstractCompositeIdMapper implements Simpl @Override public IdMapper prefixMappedProperties(String prefix) { - final MultipleIdMapper ret = new MultipleIdMapper( compositeIdClass, getServiceRegistry() ); + final MultipleIdMapper ret = new MultipleIdMapper( embedded, compositeIdClass, getServiceRegistry() ); for ( PropertyData propertyData : ids.keySet() ) { final String propertyName = propertyData.getName(); diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ToOneIdMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ToOneIdMapper.java index b969013e0a..c692728b34 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ToOneIdMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ToOneIdMapper.java @@ -19,11 +19,8 @@ import org.hibernate.envers.internal.reader.AuditReaderImplementor; import org.hibernate.envers.internal.tools.EntityTools; import org.hibernate.envers.internal.tools.query.Parameters; import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.proxy.HibernateProxy; import org.jboss.logging.Logger; -import jakarta.persistence.PersistenceException; - /** * @author Adam Warski (adam at warski dot org) * @author HernпїЅn Chanfreau @@ -64,19 +61,6 @@ public class ToOneIdMapper extends AbstractToOneMapper { // to this field. It is the responsibility of the collection to properly update it if it really changed. Object entity = nonInsertableFake ? oldObj : newObj; - // fix HHH-13760 - try to aggressively un-proxy this entity to help get the correct type of data later - // in mapToMapFromEntity. But it might fail while getImplementation() if object is deleted or other reasons. - // We catch the exception and fallback to call mapToMapFromEntity directly with the HibernateProxy entity - if ( lazyMapping && entity instanceof HibernateProxy ) { - try { - entity = ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation(); - } - catch ( PersistenceException e ) { - log.debug( "Ignore PersistenceException while initializing the entity, " + - "and fallback to call mapToMapFromEntity directly" ); - } - } - delegate.mapToMapFromEntity( newData, entity ); for ( Map.Entry entry : newData.entrySet() ) {