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.Session;
|
||||||
import org.hibernate.envers.internal.entities.PropertyData;
|
import org.hibernate.envers.internal.entities.PropertyData;
|
||||||
import org.hibernate.mapping.Component;
|
import org.hibernate.mapping.Component;
|
||||||
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
|
import org.hibernate.proxy.LazyInitializer;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,12 +27,16 @@ import org.hibernate.service.ServiceRegistry;
|
||||||
*/
|
*/
|
||||||
public class MultipleIdMapper extends AbstractCompositeIdMapper implements SimpleIdMapperBuilder {
|
public class MultipleIdMapper extends AbstractCompositeIdMapper implements SimpleIdMapperBuilder {
|
||||||
|
|
||||||
|
private final boolean embedded;
|
||||||
|
|
||||||
public MultipleIdMapper(Component component) {
|
public MultipleIdMapper(Component component) {
|
||||||
super( component.getComponentClass(), component.getServiceRegistry() );
|
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 );
|
super( compositeIdClass, serviceRegistry );
|
||||||
|
this.embedded = embedded;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -41,6 +47,12 @@ public class MultipleIdMapper extends AbstractCompositeIdMapper implements Simpl
|
||||||
@Override
|
@Override
|
||||||
public void mapToMapFromId(Session session, Map<String, Object> data, Object obj) {
|
public void mapToMapFromId(Session session, Map<String, Object> data, Object obj) {
|
||||||
if ( compositeIdClass.isInstance( 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() ) {
|
for ( Map.Entry<PropertyData, AbstractIdMapper> entry : ids.entrySet() ) {
|
||||||
final PropertyData propertyData = entry.getKey();
|
final PropertyData propertyData = entry.getKey();
|
||||||
final AbstractIdMapper idMapper = entry.getValue();
|
final AbstractIdMapper idMapper = entry.getValue();
|
||||||
|
@ -67,6 +79,12 @@ public class MultipleIdMapper extends AbstractCompositeIdMapper implements Simpl
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mapToMapFromEntity(Map<String, Object> data, Object obj) {
|
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() ) {
|
for ( IdMapper idMapper : ids.values() ) {
|
||||||
idMapper.mapToMapFromEntity( data, obj );
|
idMapper.mapToMapFromEntity( data, obj );
|
||||||
}
|
}
|
||||||
|
@ -84,7 +102,7 @@ public class MultipleIdMapper extends AbstractCompositeIdMapper implements Simpl
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IdMapper prefixMappedProperties(String prefix) {
|
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() ) {
|
for ( PropertyData propertyData : ids.keySet() ) {
|
||||||
final String propertyName = propertyData.getName();
|
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.EntityTools;
|
||||||
import org.hibernate.envers.internal.tools.query.Parameters;
|
import org.hibernate.envers.internal.tools.query.Parameters;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.proxy.HibernateProxy;
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import jakarta.persistence.PersistenceException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adam Warski (adam at warski dot org)
|
* @author Adam Warski (adam at warski dot org)
|
||||||
* @author HernпїЅn Chanfreau
|
* @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.
|
// to this field. It is the responsibility of the collection to properly update it if it really changed.
|
||||||
Object entity = nonInsertableFake ? oldObj : newObj;
|
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 );
|
delegate.mapToMapFromEntity( newData, entity );
|
||||||
|
|
||||||
for ( Map.Entry<String, Object> entry : newData.entrySet() ) {
|
for ( Map.Entry<String, Object> entry : newData.entrySet() ) {
|
||||||
|
|
Loading…
Reference in New Issue