HHH-14176 Handle embedded composite ids in envers specially to avoid lazy loading
This commit is contained in:
parent
f175581180
commit
940259dc4c
|
@ -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<String, Object> data, Object obj) {
|
||||
if ( compositeIdClass.isInstance( obj ) ) {
|
||||
if ( embedded ) {
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( obj );
|
||||
if ( lazyInitializer != null ) {
|
||||
obj = lazyInitializer.getInternalIdentifier();
|
||||
}
|
||||
}
|
||||
for ( Map.Entry<PropertyData, AbstractIdMapper> 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<String, Object> 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();
|
||||
|
|
|
@ -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<String, Object> entry : newData.entrySet() ) {
|
||||
|
|
Loading…
Reference in New Issue