HHH-7625 - Fix inverse OneToMany with a Composite key mapping failure.
This commit is contained in:
parent
1da8f01740
commit
22f23d8da0
|
@ -15,8 +15,10 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.JoinColumn;
|
||||||
|
|
||||||
|
import org.dom4j.Element;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.annotations.common.reflection.ReflectionManager;
|
import org.hibernate.annotations.common.reflection.ReflectionManager;
|
||||||
import org.hibernate.envers.ModificationStore;
|
import org.hibernate.envers.ModificationStore;
|
||||||
|
@ -68,6 +70,7 @@ import org.hibernate.mapping.ManyToOne;
|
||||||
import org.hibernate.mapping.OneToMany;
|
import org.hibernate.mapping.OneToMany;
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
import org.hibernate.mapping.Property;
|
import org.hibernate.mapping.Property;
|
||||||
|
import org.hibernate.mapping.Selectable;
|
||||||
import org.hibernate.mapping.Table;
|
import org.hibernate.mapping.Table;
|
||||||
import org.hibernate.mapping.Value;
|
import org.hibernate.mapping.Value;
|
||||||
import org.hibernate.type.BagType;
|
import org.hibernate.type.BagType;
|
||||||
|
@ -79,16 +82,14 @@ import org.hibernate.type.SetType;
|
||||||
import org.hibernate.type.SortedMapType;
|
import org.hibernate.type.SortedMapType;
|
||||||
import org.hibernate.type.SortedSetType;
|
import org.hibernate.type.SortedSetType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import org.dom4j.Element;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates metadata for a collection-valued property.
|
* Generates metadata for a collection-valued property.
|
||||||
*
|
*
|
||||||
* @author Adam Warski (adam at warski dot org)
|
* @author Adam Warski (adam at warski dot org)
|
||||||
* @author HernпїЅn Chanfreau
|
* @author HernпїЅn Chanfreau
|
||||||
|
* @author Chris Cranford
|
||||||
*/
|
*/
|
||||||
public final class CollectionMetadataGenerator {
|
public final class CollectionMetadataGenerator {
|
||||||
private static final EnversMessageLogger LOG = Logger.getMessageLogger(
|
private static final EnversMessageLogger LOG = Logger.getMessageLogger(
|
||||||
|
@ -123,8 +124,10 @@ public final class CollectionMetadataGenerator {
|
||||||
*/
|
*/
|
||||||
public CollectionMetadataGenerator(
|
public CollectionMetadataGenerator(
|
||||||
AuditMetadataGenerator mainGenerator,
|
AuditMetadataGenerator mainGenerator,
|
||||||
Collection propertyValue, CompositeMapperBuilder currentMapper,
|
Collection propertyValue,
|
||||||
String referencingEntityName, EntityXmlMappingData xmlMappingData,
|
CompositeMapperBuilder currentMapper,
|
||||||
|
String referencingEntityName,
|
||||||
|
EntityXmlMappingData xmlMappingData,
|
||||||
PropertyAuditingData propertyAuditingData) {
|
PropertyAuditingData propertyAuditingData) {
|
||||||
this.mainGenerator = mainGenerator;
|
this.mainGenerator = mainGenerator;
|
||||||
this.propertyValue = propertyValue;
|
this.propertyValue = propertyValue;
|
||||||
|
@ -164,7 +167,10 @@ public final class CollectionMetadataGenerator {
|
||||||
|
|
||||||
private MiddleIdData createMiddleIdData(IdMappingData idMappingData, String prefix, String entityName) {
|
private MiddleIdData createMiddleIdData(IdMappingData idMappingData, String prefix, String entityName) {
|
||||||
return new MiddleIdData(
|
return new MiddleIdData(
|
||||||
mainGenerator.getVerEntCfg(), idMappingData, prefix, entityName,
|
mainGenerator.getVerEntCfg(),
|
||||||
|
idMappingData,
|
||||||
|
prefix,
|
||||||
|
entityName,
|
||||||
mainGenerator.getEntitiesConfigurations().containsKey( entityName )
|
mainGenerator.getEntitiesConfigurations().containsKey( entityName )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -219,7 +225,9 @@ public final class CollectionMetadataGenerator {
|
||||||
referencingIdData,
|
referencingIdData,
|
||||||
referencedEntityName,
|
referencedEntityName,
|
||||||
referencedIdData,
|
referencedIdData,
|
||||||
isEmbeddableElementType()
|
isEmbeddableElementType(),
|
||||||
|
mappedBy,
|
||||||
|
isMappedByKey( propertyValue, mappedBy )
|
||||||
);
|
);
|
||||||
|
|
||||||
// Creating common mapper data.
|
// Creating common mapper data.
|
||||||
|
@ -300,7 +308,8 @@ public final class CollectionMetadataGenerator {
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"unchecked"})
|
@SuppressWarnings({"unchecked"})
|
||||||
private void addRelatedToXmlMapping(
|
private void addRelatedToXmlMapping(
|
||||||
Element xmlMapping, String prefix,
|
Element xmlMapping,
|
||||||
|
String prefix,
|
||||||
MetadataTools.ColumnNameIterator columnNameIterator,
|
MetadataTools.ColumnNameIterator columnNameIterator,
|
||||||
IdMappingData relatedIdMapping) {
|
IdMappingData relatedIdMapping) {
|
||||||
final Element properties = (Element) relatedIdMapping.getXmlRelationMapping().clone();
|
final Element properties = (Element) relatedIdMapping.getXmlRelationMapping().clone();
|
||||||
|
@ -827,17 +836,16 @@ public final class CollectionMetadataGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getMappedBy(Collection collectionValue) {
|
private String getMappedBy(Collection collectionValue) {
|
||||||
PersistentClass referencedClass = null;
|
final PersistentClass referencedClass = getReferenceCollectionClass( collectionValue );
|
||||||
if ( collectionValue.getElement() instanceof OneToMany ) {
|
final ValueHolder valueHolder = new ValueHolder( collectionValue );
|
||||||
final OneToMany oneToManyValue = (OneToMany) collectionValue.getElement();
|
return getMappedBy( referencedClass, valueHolder );
|
||||||
referencedClass = oneToManyValue.getAssociatedClass();
|
}
|
||||||
}
|
|
||||||
else if ( collectionValue.getElement() instanceof ManyToOne ) {
|
|
||||||
// Case for bi-directional relation with @JoinTable on the owning @ManyToOne side.
|
|
||||||
final ManyToOne manyToOneValue = (ManyToOne) collectionValue.getElement();
|
|
||||||
referencedClass = manyToOneValue.getMetadata().getEntityBinding( manyToOneValue.getReferencedEntityName() );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private String getMappedBy(Table collectionTable, PersistentClass referencedClass) {
|
||||||
|
return getMappedBy( referencedClass, new ValueHolder( collectionTable ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMappedBy(PersistentClass referencedClass, ValueHolder valueHolder) {
|
||||||
// If there's an @AuditMappedBy specified, returning it directly.
|
// If there's an @AuditMappedBy specified, returning it directly.
|
||||||
final String auditMappedBy = propertyAuditingData.getAuditMappedBy();
|
final String auditMappedBy = propertyAuditingData.getAuditMappedBy();
|
||||||
if ( auditMappedBy != null ) {
|
if ( auditMappedBy != null ) {
|
||||||
|
@ -845,7 +853,7 @@ public final class CollectionMetadataGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
// searching in referenced class
|
// searching in referenced class
|
||||||
String mappedBy = this.searchMappedBy( referencedClass, collectionValue );
|
String mappedBy = this.searchMappedBy( referencedClass, valueHolder );
|
||||||
|
|
||||||
if ( mappedBy == null ) {
|
if ( mappedBy == null ) {
|
||||||
LOG.debugf(
|
LOG.debugf(
|
||||||
|
@ -855,9 +863,9 @@ public final class CollectionMetadataGenerator {
|
||||||
);
|
);
|
||||||
|
|
||||||
PersistentClass tempClass = referencedClass;
|
PersistentClass tempClass = referencedClass;
|
||||||
while ( (mappedBy == null) && (tempClass.getSuperclass() != null) ) {
|
while ( mappedBy == null && tempClass.getSuperclass() != null ) {
|
||||||
LOG.debugf( "Searching in superclass: %s", tempClass.getSuperclass().getClassName() );
|
LOG.debugf( "Searching in superclass: %s", tempClass.getSuperclass().getClassName() );
|
||||||
mappedBy = this.searchMappedBy( tempClass.getSuperclass(), collectionValue );
|
mappedBy = this.searchMappedBy( tempClass.getSuperclass(), valueHolder );
|
||||||
tempClass = tempClass.getSuperclass();
|
tempClass = tempClass.getSuperclass();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -872,6 +880,13 @@ public final class CollectionMetadataGenerator {
|
||||||
return mappedBy;
|
return mappedBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String searchMappedBy(PersistentClass persistentClass, ValueHolder valueHolder) {
|
||||||
|
if ( valueHolder.getCollection() != null ) {
|
||||||
|
return searchMappedBy( persistentClass, valueHolder.getCollection() );
|
||||||
|
}
|
||||||
|
return searchMappedBy( persistentClass, valueHolder.getTable() );
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked"})
|
@SuppressWarnings({"unchecked"})
|
||||||
private String searchMappedBy(PersistentClass referencedClass, Collection collectionValue) {
|
private String searchMappedBy(PersistentClass referencedClass, Collection collectionValue) {
|
||||||
final Iterator<Property> assocClassProps = referencedClass.getPropertyIterator();
|
final Iterator<Property> assocClassProps = referencedClass.getPropertyIterator();
|
||||||
|
@ -885,43 +900,9 @@ public final class CollectionMetadataGenerator {
|
||||||
return property.getName();
|
return property.getName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
// HHH-7625
|
||||||
}
|
// Support ToOne relations with mappedBy that point to an @IdClass key property.
|
||||||
|
return searchMappedByKey( referencedClass, collectionValue );
|
||||||
private String getMappedBy(Table collectionTable, PersistentClass referencedClass) {
|
|
||||||
// If there's an @AuditMappedBy specified, returning it directly.
|
|
||||||
final String auditMappedBy = propertyAuditingData.getAuditMappedBy();
|
|
||||||
if ( auditMappedBy != null ) {
|
|
||||||
return auditMappedBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
// searching in referenced class
|
|
||||||
String mappedBy = this.searchMappedBy( referencedClass, collectionTable );
|
|
||||||
|
|
||||||
// not found on referenced class, searching on superclasses
|
|
||||||
if ( mappedBy == null ) {
|
|
||||||
LOG.debugf(
|
|
||||||
"Going to search the mapped by attribute for %s in superclasses of entity: %s",
|
|
||||||
propertyName,
|
|
||||||
referencedClass.getClassName()
|
|
||||||
);
|
|
||||||
|
|
||||||
PersistentClass tempClass = referencedClass;
|
|
||||||
while ( (mappedBy == null) && (tempClass.getSuperclass() != null) ) {
|
|
||||||
LOG.debugf( "Searching in superclass: %s", tempClass.getSuperclass().getClassName() );
|
|
||||||
mappedBy = this.searchMappedBy( tempClass.getSuperclass(), collectionTable );
|
|
||||||
tempClass = tempClass.getSuperclass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( mappedBy == null ) {
|
|
||||||
throw new MappingException(
|
|
||||||
"Unable to read the mapped by attribute for " + propertyName + " in "
|
|
||||||
+ referencedClass.getClassName() + "!"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mappedBy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked"})
|
@SuppressWarnings({"unchecked"})
|
||||||
|
@ -940,4 +921,69 @@ public final class CollectionMetadataGenerator {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked"})
|
||||||
|
private String searchMappedByKey(PersistentClass referencedClass, Collection collectionValue) {
|
||||||
|
final Iterator<Value> assocIdClassProps = referencedClass.getKeyClosureIterator();
|
||||||
|
while ( assocIdClassProps.hasNext() ) {
|
||||||
|
final Value value = assocIdClassProps.next();
|
||||||
|
// make sure its a 'Component' because IdClass is registered as this type.
|
||||||
|
if ( value instanceof Component ) {
|
||||||
|
final Component component = (Component) value;
|
||||||
|
final Iterator<Property> componentPropertyIterator = component.getPropertyIterator();
|
||||||
|
while ( componentPropertyIterator.hasNext() ) {
|
||||||
|
final Property property = componentPropertyIterator.next();
|
||||||
|
final Iterator<Selectable> propertySelectables = property.getValue().getColumnIterator();
|
||||||
|
final Iterator<Selectable> collectionSelectables = collectionValue.getKey().getColumnIterator();
|
||||||
|
if ( Tools.iteratorsContentEqual( propertySelectables, collectionSelectables ) ) {
|
||||||
|
return property.getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PersistentClass getReferenceCollectionClass(Collection collectionValue) {
|
||||||
|
PersistentClass referencedClass = null;
|
||||||
|
if ( collectionValue.getElement() instanceof OneToMany ) {
|
||||||
|
final OneToMany oneToManyValue = (OneToMany) collectionValue.getElement();
|
||||||
|
referencedClass = oneToManyValue.getAssociatedClass();
|
||||||
|
}
|
||||||
|
else if ( collectionValue.getElement() instanceof ManyToOne ) {
|
||||||
|
// Case for bi-directional relation with @JoinTable on the owning @ManyToOne side.
|
||||||
|
final ManyToOne manyToOneValue = (ManyToOne) collectionValue.getElement();
|
||||||
|
referencedClass = manyToOneValue.getMetadata().getEntityBinding( manyToOneValue.getReferencedEntityName() );
|
||||||
|
}
|
||||||
|
return referencedClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isMappedByKey(Collection collectionValue, String mappedBy) {
|
||||||
|
final PersistentClass referencedClass = getReferenceCollectionClass( collectionValue );
|
||||||
|
if ( referencedClass != null ) {
|
||||||
|
final String keyMappedBy = searchMappedByKey( referencedClass, collectionValue );
|
||||||
|
return mappedBy.equals( keyMappedBy );
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ValueHolder {
|
||||||
|
private Collection collection;
|
||||||
|
private Table table;
|
||||||
|
|
||||||
|
public ValueHolder(Collection collection) {
|
||||||
|
this.collection = collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueHolder(Table table) {
|
||||||
|
this.table = table;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection getCollection() {
|
||||||
|
return collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Table getTable() {
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.hibernate.service.ServiceRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adam Warski (adam at warski dot org)
|
* @author Adam Warski (adam at warski dot org)
|
||||||
|
* @author Chris Cranford
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractIdMapper implements IdMapper {
|
public abstract class AbstractIdMapper implements IdMapper {
|
||||||
private final ServiceRegistry serviceRegistry;
|
private final ServiceRegistry serviceRegistry;
|
||||||
|
@ -119,6 +120,25 @@ public abstract class AbstractIdMapper implements IdMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addNamedIdEqualsToQuery(Parameters parameters, String prefix1, IdMapper mapper, boolean equals) {
|
||||||
|
final List<QueryParameterData> paramDatas1 = mapToQueryParametersFromId( null );
|
||||||
|
final List<QueryParameterData> paramDatas2 = mapper.mapToQueryParametersFromId( null );
|
||||||
|
|
||||||
|
final Parameters parametersToUse = getParametersToUse( parameters, paramDatas1 );
|
||||||
|
final Iterator<QueryParameterData> paramDataIter1 = paramDatas1.iterator();
|
||||||
|
final Iterator<QueryParameterData> paramDataIter2 = paramDatas2.iterator();
|
||||||
|
while ( paramDataIter1.hasNext() ) {
|
||||||
|
final QueryParameterData paramData1 = paramDataIter1.next();
|
||||||
|
final QueryParameterData paramData2 = paramDataIter2.next();
|
||||||
|
parametersToUse.addWhereWithNamedParam(
|
||||||
|
paramData1.getProperty( prefix1 ),
|
||||||
|
equals ? "=" : "<>",
|
||||||
|
paramData2.getQueryParameterName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void handleNullValue(Parameters parameters, String alias, String propertyName, boolean equals) {
|
private void handleNullValue(Parameters parameters, String alias, String propertyName, boolean equals) {
|
||||||
if ( equals ) {
|
if ( equals ) {
|
||||||
parameters.addNullRestriction( alias, propertyName );
|
parameters.addNullRestriction( alias, propertyName );
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.hibernate.service.ServiceRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adam Warski (adam at warski dot org)
|
* @author Adam Warski (adam at warski dot org)
|
||||||
|
* @author Chris Cranford
|
||||||
*/
|
*/
|
||||||
public interface IdMapper {
|
public interface IdMapper {
|
||||||
ServiceRegistry getServiceRegistry();
|
ServiceRegistry getServiceRegistry();
|
||||||
|
@ -96,4 +97,17 @@ public interface IdMapper {
|
||||||
* @param equals Should this query express the "=" relation or the "<>" relation.
|
* @param equals Should this query express the "=" relation or the "<>" relation.
|
||||||
*/
|
*/
|
||||||
void addNamedIdEqualsToQuery(Parameters parameters, String prefix, boolean equals);
|
void addNamedIdEqualsToQuery(Parameters parameters, String prefix, boolean equals);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds query statements, which contains named parameters that express the property that the id of the entity
|
||||||
|
* with alias prefix is equal to the given object using the specified mapper.
|
||||||
|
*
|
||||||
|
* @param parameters Parameters, to which to add the statements.
|
||||||
|
* @param prefix Prefix to add to the properties (may be null).
|
||||||
|
* @param mapper The identifier mapper to use
|
||||||
|
* @param equals Should this query express the "=" relation or the "<>" relation.
|
||||||
|
*
|
||||||
|
* @since 5.2.2
|
||||||
|
*/
|
||||||
|
void addNamedIdEqualsToQuery(Parameters parameters, String prefix, IdMapper mapper, boolean equals);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@ package org.hibernate.envers.internal.entities.mapper.relation.query;
|
||||||
|
|
||||||
import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration;
|
import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration;
|
||||||
import org.hibernate.envers.configuration.internal.GlobalConfiguration;
|
import org.hibernate.envers.configuration.internal.GlobalConfiguration;
|
||||||
|
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.relation.MiddleIdData;
|
import org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData;
|
||||||
import org.hibernate.envers.internal.tools.query.Parameters;
|
import org.hibernate.envers.internal.tools.query.Parameters;
|
||||||
import org.hibernate.envers.internal.tools.query.QueryBuilder;
|
import org.hibernate.envers.internal.tools.query.QueryBuilder;
|
||||||
|
@ -23,17 +25,35 @@ import static org.hibernate.envers.internal.entities.mapper.relation.query.Query
|
||||||
*
|
*
|
||||||
* @author Adam Warski (adam at warski dot org)
|
* @author Adam Warski (adam at warski dot org)
|
||||||
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||||
|
* @author Chris Cranford
|
||||||
*/
|
*/
|
||||||
public final class OneAuditEntityQueryGenerator extends AbstractRelationQueryGenerator {
|
public final class OneAuditEntityQueryGenerator extends AbstractRelationQueryGenerator {
|
||||||
private final String queryString;
|
private final String queryString;
|
||||||
private final String queryRemovedString;
|
private final String queryRemovedString;
|
||||||
|
private final String mappedBy;
|
||||||
|
private final boolean multipleIdMapperKey;
|
||||||
|
|
||||||
public OneAuditEntityQueryGenerator(
|
public OneAuditEntityQueryGenerator(
|
||||||
GlobalConfiguration globalCfg, AuditEntitiesConfiguration verEntCfg,
|
GlobalConfiguration globalCfg,
|
||||||
AuditStrategy auditStrategy, MiddleIdData referencingIdData,
|
AuditEntitiesConfiguration verEntCfg,
|
||||||
String referencedEntityName, MiddleIdData referencedIdData, boolean revisionTypeInId) {
|
AuditStrategy auditStrategy,
|
||||||
|
MiddleIdData referencingIdData,
|
||||||
|
String referencedEntityName,
|
||||||
|
MiddleIdData referencedIdData,
|
||||||
|
boolean revisionTypeInId,
|
||||||
|
String mappedBy,
|
||||||
|
boolean mappedByKey) {
|
||||||
super( verEntCfg, referencingIdData, revisionTypeInId );
|
super( verEntCfg, referencingIdData, revisionTypeInId );
|
||||||
|
|
||||||
|
this.mappedBy = mappedBy;
|
||||||
|
|
||||||
|
if ( ( referencedIdData.getOriginalMapper() instanceof MultipleIdMapper ) && mappedByKey ) {
|
||||||
|
multipleIdMapperKey = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
multipleIdMapperKey = false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The valid query that we need to create:
|
* The valid query that we need to create:
|
||||||
* SELECT e FROM versionsReferencedEntity e
|
* SELECT e FROM versionsReferencedEntity e
|
||||||
|
@ -72,8 +92,17 @@ public final class OneAuditEntityQueryGenerator extends AbstractRelationQueryGen
|
||||||
final QueryBuilder qb = new QueryBuilder( versionsReferencedEntityName, REFERENCED_ENTITY_ALIAS );
|
final QueryBuilder qb = new QueryBuilder( versionsReferencedEntityName, REFERENCED_ENTITY_ALIAS );
|
||||||
qb.addProjection( null, REFERENCED_ENTITY_ALIAS, null, false );
|
qb.addProjection( null, REFERENCED_ENTITY_ALIAS, null, false );
|
||||||
// WHERE
|
// WHERE
|
||||||
// e.id_ref_ed = :id_ref_ed
|
if ( multipleIdMapperKey ) {
|
||||||
referencingIdData.getPrefixedMapper().addNamedIdEqualsToQuery( qb.getRootParameters(), null, true );
|
// HHH-7625
|
||||||
|
// support @OneToMany(mappedBy) to @ManyToOne @IdClass attribute.
|
||||||
|
// e.originalId.id_ref_ed.id = :id_ref_ed
|
||||||
|
final IdMapper mapper = getMultipleIdPrefixedMapper();
|
||||||
|
mapper.addNamedIdEqualsToQuery( qb.getRootParameters(), null, referencingIdData.getPrefixedMapper(), true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// e.id_ref_ed = :id_ref_ed
|
||||||
|
referencingIdData.getPrefixedMapper().addNamedIdEqualsToQuery( qb.getRootParameters(), null, true );
|
||||||
|
}
|
||||||
return qb;
|
return qb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,4 +153,9 @@ public final class OneAuditEntityQueryGenerator extends AbstractRelationQueryGen
|
||||||
protected String getQueryRemovedString() {
|
protected String getQueryRemovedString() {
|
||||||
return queryRemovedString;
|
return queryRemovedString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IdMapper getMultipleIdPrefixedMapper() {
|
||||||
|
final String prefix = verEntCfg.getOriginalIdPropName() + "." + mappedBy + ".";
|
||||||
|
return referencingIdData.getOriginalMapper().prefixMappedProperties( prefix );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue