HHH-11748 - Fix relatedId queries against associated entities in entity identifier mappings.
This commit is contained in:
parent
ac15d45da2
commit
843cce998f
|
@ -10,7 +10,6 @@ import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.dom4j.Element;
|
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.boot.spi.MetadataImplementor;
|
import org.hibernate.boot.spi.MetadataImplementor;
|
||||||
|
@ -48,6 +47,9 @@ import org.hibernate.type.ManyToOneType;
|
||||||
import org.hibernate.type.OneToOneType;
|
import org.hibernate.type.OneToOneType;
|
||||||
import org.hibernate.type.TimestampType;
|
import org.hibernate.type.TimestampType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
import org.dom4j.Element;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -743,6 +745,10 @@ public final class AuditMetadataGenerator {
|
||||||
// Mapping unjoined properties
|
// Mapping unjoined properties
|
||||||
final Element parent = xmlMappingData.getClassMapping();
|
final Element parent = xmlMappingData.getClassMapping();
|
||||||
|
|
||||||
|
// HHH-11748 - Generate a second pass for identifiers
|
||||||
|
// This is useful for situations where @Id point to @ManyToOne and @OneToOne associations.
|
||||||
|
idMetadataGenerator.generateSecondPass( entityName, pc );
|
||||||
|
|
||||||
addProperties(
|
addProperties(
|
||||||
parent,
|
parent,
|
||||||
pc.getUnjoinedPropertyIterator(),
|
pc.getUnjoinedPropertyIterator(),
|
||||||
|
|
|
@ -16,6 +16,7 @@ import org.hibernate.envers.internal.entities.IdMappingData;
|
||||||
import org.hibernate.envers.internal.entities.PropertyData;
|
import org.hibernate.envers.internal.entities.PropertyData;
|
||||||
import org.hibernate.envers.internal.entities.mapper.SimpleMapperBuilder;
|
import org.hibernate.envers.internal.entities.mapper.SimpleMapperBuilder;
|
||||||
import org.hibernate.envers.internal.entities.mapper.id.EmbeddedIdMapper;
|
import org.hibernate.envers.internal.entities.mapper.id.EmbeddedIdMapper;
|
||||||
|
import org.hibernate.envers.internal.entities.mapper.id.IdMapper;
|
||||||
import org.hibernate.envers.internal.entities.mapper.id.MultipleIdMapper;
|
import org.hibernate.envers.internal.entities.mapper.id.MultipleIdMapper;
|
||||||
import org.hibernate.envers.internal.entities.mapper.id.SimpleIdMapperBuilder;
|
import org.hibernate.envers.internal.entities.mapper.id.SimpleIdMapperBuilder;
|
||||||
import org.hibernate.envers.internal.entities.mapper.id.SingleIdMapper;
|
import org.hibernate.envers.internal.entities.mapper.id.SingleIdMapper;
|
||||||
|
@ -23,6 +24,7 @@ import org.hibernate.envers.internal.tools.ReflectionTools;
|
||||||
import org.hibernate.mapping.Component;
|
import org.hibernate.mapping.Component;
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
import org.hibernate.mapping.Property;
|
import org.hibernate.mapping.Property;
|
||||||
|
import org.hibernate.mapping.ToOne;
|
||||||
import org.hibernate.type.ManyToOneType;
|
import org.hibernate.type.ManyToOneType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
@ -89,6 +91,41 @@ public final class IdMetadataGenerator {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void generateSecondPass(String entityName, PersistentClass persistentClass) {
|
||||||
|
final Component identifierMapper = persistentClass.getIdentifierMapper();
|
||||||
|
final Property identifierProperty = persistentClass.getIdentifierProperty();
|
||||||
|
if ( identifierMapper != null ) {
|
||||||
|
generateSecondPass( entityName, identifierMapper );
|
||||||
|
}
|
||||||
|
else if ( identifierProperty != null && identifierProperty.isComposite() ) {
|
||||||
|
final Component component = (Component) identifierProperty.getValue();
|
||||||
|
generateSecondPass( entityName, component );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateSecondPass(String entityName, Component component) {
|
||||||
|
Iterator properties = component.getPropertyIterator();
|
||||||
|
while ( properties.hasNext() ) {
|
||||||
|
final Property property = (Property) properties.next();
|
||||||
|
if ( property.getValue() instanceof ToOne ) {
|
||||||
|
final PropertyAuditingData propertyData = getIdPersistentPropertyAuditingData( property );
|
||||||
|
final String referencedEntityName = ( (ToOne) property.getValue() ).getReferencedEntityName();
|
||||||
|
|
||||||
|
final String prefix = mainGenerator.getVerEntCfg().getOriginalIdPropName() + "." + propertyData.getName();
|
||||||
|
final IdMapper relMapper = mainGenerator.getEntitiesConfigurations().get( referencedEntityName ).getIdMapper();
|
||||||
|
final IdMapper prefixedMapper = relMapper.prefixMappedProperties( prefix + "." );
|
||||||
|
|
||||||
|
mainGenerator.getEntitiesConfigurations().get( entityName ).addToOneRelation(
|
||||||
|
prefix,
|
||||||
|
referencedEntityName,
|
||||||
|
prefixedMapper,
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked"})
|
@SuppressWarnings({"unchecked"})
|
||||||
IdMappingData addId(PersistentClass pc, boolean audited) {
|
IdMappingData addId(PersistentClass pc, boolean audited) {
|
||||||
// Xml mapping which will be used for relations
|
// Xml mapping which will be used for relations
|
||||||
|
|
|
@ -89,6 +89,17 @@ public abstract class CriteriaTools {
|
||||||
if ( identifierPropertyNames.contains( propertyName ) ) {
|
if ( identifierPropertyNames.contains( propertyName ) ) {
|
||||||
propertyName = enversService.getAuditEntitiesConfiguration().getOriginalIdPropName() + "." + propertyName;
|
propertyName = enversService.getAuditEntitiesConfiguration().getOriginalIdPropName() + "." + propertyName;
|
||||||
}
|
}
|
||||||
|
else if ( propertyName != null ) {
|
||||||
|
// if property starts with an identifier prefix ( e.g. embedded ids ), substitute with the originalId property
|
||||||
|
// because Envers performs replacement this automatically during the mapping.
|
||||||
|
for ( String identifierPropertyName : identifierPropertyNames ) {
|
||||||
|
if ( propertyName.startsWith( identifierPropertyName + "." ) ) {
|
||||||
|
propertyName = enversService.getAuditEntitiesConfiguration().getOriginalIdPropName() +
|
||||||
|
propertyName.substring( identifierPropertyName.length() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return propertyName;
|
return propertyName;
|
||||||
|
|
Loading…
Reference in New Issue