HHH-12018 - Revert fix for HHH-11841: Audit query QueryException on maps using entity-types as keys.

This commit is contained in:
Chris Cranford 2017-10-19 01:51:19 -04:00
parent 2ace60ea79
commit dd2bf67ac9
9 changed files with 40 additions and 50 deletions

View File

@ -76,6 +76,7 @@ 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;
import org.hibernate.type.ComponentType; import org.hibernate.type.ComponentType;
import org.hibernate.type.CustomType;
import org.hibernate.type.ListType; import org.hibernate.type.ListType;
import org.hibernate.type.ManyToOneType; import org.hibernate.type.ManyToOneType;
import org.hibernate.type.MapType; import org.hibernate.type.MapType;
@ -448,8 +449,7 @@ public final class CollectionMetadataGenerator {
mainGenerator.getAuditStrategy(), mainGenerator.getAuditStrategy(),
referencingIdData, referencingIdData,
auditMiddleEntityName, auditMiddleEntityName,
isKeyRevisionTypeInId(), isRevisionTypeInId()
isElementRevisionTypeInId()
); );
// Adding the XML mapping for the referencing entity, if the relation isn't inverse. // Adding the XML mapping for the referencing entity, if the relation isn't inverse.
@ -471,7 +471,7 @@ public final class CollectionMetadataGenerator {
queryGeneratorBuilder, queryGeneratorBuilder,
referencedPrefix, referencedPrefix,
propertyAuditingData.getJoinTable().inverseJoinColumns(), propertyAuditingData.getJoinTable().inverseJoinColumns(),
!isLobMapElementType() && isMapElementInPrimaryKey() !isLobMapElementType()
); );
// ****** // ******
@ -855,9 +855,9 @@ public final class CollectionMetadataGenerator {
// Adding the revision type property to the entity xml. // Adding the revision type property to the entity xml.
mainGenerator.addRevisionType( mainGenerator.addRevisionType(
isElementRevisionTypeInId() ? middleEntityXmlId : middleEntityXml, isRevisionTypeInId() ? middleEntityXmlId : middleEntityXml,
middleEntityXml, middleEntityXml,
isElementRevisionTypeInId() isRevisionTypeInId()
); );
// All other properties should also be part of the primary key of the middle entity. // All other properties should also be part of the primary key of the middle entity.
@ -1028,7 +1028,7 @@ public final class CollectionMetadataGenerator {
* *
* @return {@code true} if the revision type should be part of the primary key, otherwise {@code false}. * @return {@code true} if the revision type should be part of the primary key, otherwise {@code false}.
*/ */
private boolean isElementRevisionTypeInId() { private boolean isRevisionTypeInId() {
return isEmbeddableElementType() || isLobMapElementType(); return isEmbeddableElementType() || isLobMapElementType();
} }

View File

@ -35,8 +35,7 @@ public final class QueryGeneratorBuilder {
private final MiddleIdData referencingIdData; private final MiddleIdData referencingIdData;
private final String auditMiddleEntityName; private final String auditMiddleEntityName;
private final List<MiddleIdData> idDatas; private final List<MiddleIdData> idDatas;
private final boolean elementRevisionTypeInId; private final boolean revisionTypeInId;
private final boolean keyRevisionTypeInId;
QueryGeneratorBuilder( QueryGeneratorBuilder(
GlobalConfiguration globalCfg, GlobalConfiguration globalCfg,
@ -44,15 +43,13 @@ public final class QueryGeneratorBuilder {
AuditStrategy auditStrategy, AuditStrategy auditStrategy,
MiddleIdData referencingIdData, MiddleIdData referencingIdData,
String auditMiddleEntityName, String auditMiddleEntityName,
boolean keyRevisionTypeInId, boolean revisionTypeInId) {
boolean elementRevisionTypeInId) {
this.globalCfg = globalCfg; this.globalCfg = globalCfg;
this.verEntCfg = verEntCfg; this.verEntCfg = verEntCfg;
this.auditStrategy = auditStrategy; this.auditStrategy = auditStrategy;
this.referencingIdData = referencingIdData; this.referencingIdData = referencingIdData;
this.auditMiddleEntityName = auditMiddleEntityName; this.auditMiddleEntityName = auditMiddleEntityName;
this.keyRevisionTypeInId = keyRevisionTypeInId; this.revisionTypeInId = revisionTypeInId;
this.elementRevisionTypeInId = elementRevisionTypeInId;
idDatas = new ArrayList<>(); idDatas = new ArrayList<>();
} }
@ -65,20 +62,20 @@ public final class QueryGeneratorBuilder {
if ( idDatas.size() == 0 ) { if ( idDatas.size() == 0 ) {
return new OneEntityQueryGenerator( return new OneEntityQueryGenerator(
verEntCfg, auditStrategy, auditMiddleEntityName, referencingIdData, verEntCfg, auditStrategy, auditMiddleEntityName, referencingIdData,
elementRevisionTypeInId, componentDatas revisionTypeInId, componentDatas
); );
} }
else if ( idDatas.size() == 1 ) { else if ( idDatas.size() == 1 ) {
if ( idDatas.get( 0 ).isAudited() ) { if ( idDatas.get( 0 ).isAudited() ) {
return new TwoEntityQueryGenerator( return new TwoEntityQueryGenerator(
globalCfg, verEntCfg, auditStrategy, auditMiddleEntityName, referencingIdData, globalCfg, verEntCfg, auditStrategy, auditMiddleEntityName, referencingIdData,
idDatas.get( 0 ), elementRevisionTypeInId, keyRevisionTypeInId, componentDatas idDatas.get( 0 ), revisionTypeInId, componentDatas
); );
} }
else { else {
return new TwoEntityOneAuditedQueryGenerator( return new TwoEntityOneAuditedQueryGenerator(
verEntCfg, auditStrategy, auditMiddleEntityName, referencingIdData, verEntCfg, auditStrategy, auditMiddleEntityName, referencingIdData,
idDatas.get( 0 ), elementRevisionTypeInId, componentDatas idDatas.get( 0 ), revisionTypeInId, componentDatas
); );
} }
} }
@ -92,7 +89,7 @@ public final class QueryGeneratorBuilder {
return new ThreeEntityQueryGenerator( return new ThreeEntityQueryGenerator(
globalCfg, verEntCfg, auditStrategy, auditMiddleEntityName, referencingIdData, globalCfg, verEntCfg, auditStrategy, auditMiddleEntityName, referencingIdData,
idDatas.get( 0 ), idDatas.get( 1 ), elementRevisionTypeInId, componentDatas idDatas.get( 0 ), idDatas.get( 1 ), revisionTypeInId, componentDatas
); );
} }
else { else {

View File

@ -29,18 +29,15 @@ import static org.hibernate.envers.internal.entities.mapper.relation.query.Query
public abstract class AbstractRelationQueryGenerator implements RelationQueryGenerator { public abstract class AbstractRelationQueryGenerator implements RelationQueryGenerator {
protected final AuditEntitiesConfiguration verEntCfg; protected final AuditEntitiesConfiguration verEntCfg;
protected final MiddleIdData referencingIdData; protected final MiddleIdData referencingIdData;
protected final boolean keyRevisionTypeInId; protected final boolean revisionTypeInId;
protected final boolean elementRevisionTypeInId;
protected AbstractRelationQueryGenerator( protected AbstractRelationQueryGenerator(
AuditEntitiesConfiguration verEntCfg, AuditEntitiesConfiguration verEntCfg,
MiddleIdData referencingIdData, MiddleIdData referencingIdData,
boolean keyRevisionTypeInId, boolean revisionTypeInId) {
boolean elementRevisionTypeInId) {
this.verEntCfg = verEntCfg; this.verEntCfg = verEntCfg;
this.referencingIdData = referencingIdData; this.referencingIdData = referencingIdData;
this.keyRevisionTypeInId = keyRevisionTypeInId; this.revisionTypeInId = revisionTypeInId;
this.elementRevisionTypeInId = elementRevisionTypeInId;
} }
/** /**
@ -68,14 +65,6 @@ public abstract class AbstractRelationQueryGenerator implements RelationQueryGen
return query; return query;
} }
protected String getElementRevisionTypePath() {
return getRevisionTypePath( this.elementRevisionTypeInId );
}
protected String getKeyRevisionTypePath() {
return getRevisionTypePath( this.keyRevisionTypeInId );
}
protected String queryToString(QueryBuilder query) { protected String queryToString(QueryBuilder query) {
return queryToString( query, Collections.emptyMap() ); return queryToString( query, Collections.emptyMap() );
} }
@ -86,7 +75,7 @@ public abstract class AbstractRelationQueryGenerator implements RelationQueryGen
return sb.toString(); return sb.toString();
} }
private String getRevisionTypePath(boolean revisionTypeInId) { protected String getRevisionTypePath() {
return revisionTypeInId return revisionTypeInId
? verEntCfg.getOriginalIdPropName() + "." + verEntCfg.getRevisionTypePropName() ? verEntCfg.getOriginalIdPropName() + "." + verEntCfg.getRevisionTypePropName()
: verEntCfg.getRevisionTypePropName(); : verEntCfg.getRevisionTypePropName();

View File

@ -43,7 +43,7 @@ public final class OneAuditEntityQueryGenerator extends AbstractRelationQueryGen
boolean revisionTypeInId, boolean revisionTypeInId,
String mappedBy, String mappedBy,
boolean mappedByKey) { boolean mappedByKey) {
super( verEntCfg, referencingIdData, revisionTypeInId, revisionTypeInId ); super( verEntCfg, referencingIdData, revisionTypeInId );
this.mappedBy = mappedBy; this.mappedBy = mappedBy;
@ -124,7 +124,7 @@ public final class OneAuditEntityQueryGenerator extends AbstractRelationQueryGen
true true
); );
// e.revision_type != DEL // e.revision_type != DEL
rootParameters.addWhereWithNamedParam( getElementRevisionTypePath(), false, "!=", DEL_REVISION_TYPE_PARAMETER ); rootParameters.addWhereWithNamedParam( getRevisionTypePath(), false, "!=", DEL_REVISION_TYPE_PARAMETER );
} }
/** /**
@ -143,7 +143,7 @@ public final class OneAuditEntityQueryGenerator extends AbstractRelationQueryGen
// e.revision = :revision // e.revision = :revision
removed.addWhereWithNamedParam( verEntCfg.getRevisionNumberPath(), false, "=", REVISION_PARAMETER ); removed.addWhereWithNamedParam( verEntCfg.getRevisionNumberPath(), false, "=", REVISION_PARAMETER );
// e.revision_type = DEL // e.revision_type = DEL
removed.addWhereWithNamedParam( getElementRevisionTypePath(), false, "=", DEL_REVISION_TYPE_PARAMETER ); removed.addWhereWithNamedParam( getRevisionTypePath(), false, "=", DEL_REVISION_TYPE_PARAMETER );
} }
@Override @Override

View File

@ -31,7 +31,7 @@ public final class OneEntityQueryGenerator extends AbstractRelationQueryGenerato
AuditEntitiesConfiguration verEntCfg, AuditStrategy auditStrategy, AuditEntitiesConfiguration verEntCfg, AuditStrategy auditStrategy,
String versionsMiddleEntityName, MiddleIdData referencingIdData, String versionsMiddleEntityName, MiddleIdData referencingIdData,
boolean revisionTypeInId, MiddleComponentData... componentData) { boolean revisionTypeInId, MiddleComponentData... componentData) {
super( verEntCfg, referencingIdData, revisionTypeInId, revisionTypeInId ); super( verEntCfg, referencingIdData, revisionTypeInId );
/* /*
* The valid query that we need to create: * The valid query that we need to create:
@ -99,7 +99,7 @@ public final class OneEntityQueryGenerator extends AbstractRelationQueryGenerato
originalIdPropertyName, MIDDLE_ENTITY_ALIAS, inclusive, componentData originalIdPropertyName, MIDDLE_ENTITY_ALIAS, inclusive, componentData
); );
// ee.revision_type != DEL // ee.revision_type != DEL
rootParameters.addWhereWithNamedParam( getElementRevisionTypePath(), "!=", DEL_REVISION_TYPE_PARAMETER ); rootParameters.addWhereWithNamedParam( getRevisionTypePath(), "!=", DEL_REVISION_TYPE_PARAMETER );
} }
/** /**
@ -118,7 +118,7 @@ public final class OneEntityQueryGenerator extends AbstractRelationQueryGenerato
// ee.revision = :revision // ee.revision = :revision
removed.addWhereWithNamedParam( verEntCfg.getRevisionNumberPath(), "=", REVISION_PARAMETER ); removed.addWhereWithNamedParam( verEntCfg.getRevisionNumberPath(), "=", REVISION_PARAMETER );
// ee.revision_type = DEL // ee.revision_type = DEL
removed.addWhereWithNamedParam( getElementRevisionTypePath(), "=", DEL_REVISION_TYPE_PARAMETER ); removed.addWhereWithNamedParam( getRevisionTypePath(), "=", DEL_REVISION_TYPE_PARAMETER );
} }
@Override @Override

View File

@ -38,7 +38,7 @@ public final class ThreeEntityQueryGenerator extends AbstractRelationQueryGenera
MiddleIdData referencingIdData, MiddleIdData referencedIdData, MiddleIdData referencingIdData, MiddleIdData referencedIdData,
MiddleIdData indexIdData, boolean revisionTypeInId, MiddleIdData indexIdData, boolean revisionTypeInId,
MiddleComponentData... componentData) { MiddleComponentData... componentData) {
super( verEntCfg, referencingIdData, revisionTypeInId, revisionTypeInId ); super( verEntCfg, referencingIdData, revisionTypeInId );
/* /*
* The valid query that we need to create: * The valid query that we need to create:
@ -148,7 +148,7 @@ public final class ThreeEntityQueryGenerator extends AbstractRelationQueryGenera
final String revisionPropertyPath = verEntCfg.getRevisionNumberPath(); final String revisionPropertyPath = verEntCfg.getRevisionNumberPath();
final String originalIdPropertyName = verEntCfg.getOriginalIdPropName(); final String originalIdPropertyName = verEntCfg.getOriginalIdPropName();
final String eeOriginalIdPropertyPath = MIDDLE_ENTITY_ALIAS + "." + originalIdPropertyName; final String eeOriginalIdPropertyPath = MIDDLE_ENTITY_ALIAS + "." + originalIdPropertyName;
final String revisionTypePropName = getElementRevisionTypePath(); final String revisionTypePropName = getRevisionTypePath();
// (selecting e entities at revision :revision) // (selecting e entities at revision :revision)
// --> based on auditStrategy (see above) // --> based on auditStrategy (see above)
auditStrategy.addEntityAtRevisionRestriction( auditStrategy.addEntityAtRevisionRestriction(
@ -219,7 +219,7 @@ public final class ThreeEntityQueryGenerator extends AbstractRelationQueryGenera
// Restrictions to match all rows deleted at exactly given revision. // Restrictions to match all rows deleted at exactly given revision.
final Parameters removed = disjoint.addSubParameters( "and" ); final Parameters removed = disjoint.addSubParameters( "and" );
final String revisionPropertyPath = verEntCfg.getRevisionNumberPath(); final String revisionPropertyPath = verEntCfg.getRevisionNumberPath();
final String revisionTypePropName = getElementRevisionTypePath(); final String revisionTypePropName = getRevisionTypePath();
// Excluding current revision, because we need to match data valid at the previous one. // Excluding current revision, because we need to match data valid at the previous one.
createValidDataRestrictions( createValidDataRestrictions(
globalCfg, auditStrategy, referencedIdData, versionsMiddleEntityName, remQb, valid, false, indexIdData, componentData globalCfg, auditStrategy, referencedIdData, versionsMiddleEntityName, remQb, valid, false, indexIdData, componentData

View File

@ -31,9 +31,9 @@ public final class TwoEntityOneAuditedQueryGenerator extends AbstractRelationQue
public TwoEntityOneAuditedQueryGenerator( public TwoEntityOneAuditedQueryGenerator(
AuditEntitiesConfiguration verEntCfg, AuditStrategy auditStrategy, AuditEntitiesConfiguration verEntCfg, AuditStrategy auditStrategy,
String versionsMiddleEntityName, MiddleIdData referencingIdData, String versionsMiddleEntityName, MiddleIdData referencingIdData,
MiddleIdData referencedIdData, boolean elementRevisionTypeInId, MiddleIdData referencedIdData, boolean revisionTypeInId,
MiddleComponentData... componentData) { MiddleComponentData... componentData) {
super( verEntCfg, referencingIdData, elementRevisionTypeInId, elementRevisionTypeInId ); super( verEntCfg, referencingIdData, revisionTypeInId );
/* /*
* The valid query that we need to create: * The valid query that we need to create:
@ -112,7 +112,7 @@ public final class TwoEntityOneAuditedQueryGenerator extends AbstractRelationQue
originalIdPropertyName, MIDDLE_ENTITY_ALIAS, true, componentData originalIdPropertyName, MIDDLE_ENTITY_ALIAS, true, componentData
); );
// ee.revision_type != DEL // ee.revision_type != DEL
rootParameters.addWhereWithNamedParam( getElementRevisionTypePath(), "!=", DEL_REVISION_TYPE_PARAMETER ); rootParameters.addWhereWithNamedParam( getRevisionTypePath(), "!=", DEL_REVISION_TYPE_PARAMETER );
} }
/** /**
@ -130,7 +130,7 @@ public final class TwoEntityOneAuditedQueryGenerator extends AbstractRelationQue
// ee.revision = :revision // ee.revision = :revision
removed.addWhereWithNamedParam( verEntCfg.getRevisionNumberPath(), "=", REVISION_PARAMETER ); removed.addWhereWithNamedParam( verEntCfg.getRevisionNumberPath(), "=", REVISION_PARAMETER );
// ee.revision_type = DEL // ee.revision_type = DEL
removed.addWhereWithNamedParam( getElementRevisionTypePath(), "=", DEL_REVISION_TYPE_PARAMETER ); removed.addWhereWithNamedParam( getRevisionTypePath(), "=", DEL_REVISION_TYPE_PARAMETER );
} }
@Override @Override

View File

@ -34,8 +34,8 @@ public final class TwoEntityQueryGenerator extends AbstractRelationQueryGenerato
GlobalConfiguration globalCfg, AuditEntitiesConfiguration verEntCfg, GlobalConfiguration globalCfg, AuditEntitiesConfiguration verEntCfg,
AuditStrategy auditStrategy, String versionsMiddleEntityName, AuditStrategy auditStrategy, String versionsMiddleEntityName,
MiddleIdData referencingIdData, MiddleIdData referencedIdData, MiddleIdData referencingIdData, MiddleIdData referencedIdData,
boolean elementRevisionTypeInId, boolean keyRevisionTypeInId, MiddleComponentData... componentData) { boolean revisionTypeInId, MiddleComponentData... componentData) {
super( verEntCfg, referencingIdData, keyRevisionTypeInId, elementRevisionTypeInId ); super( verEntCfg, referencingIdData, revisionTypeInId );
/* /*
* The valid query that we need to create: * The valid query that we need to create:
@ -120,7 +120,7 @@ public final class TwoEntityQueryGenerator extends AbstractRelationQueryGenerato
final String revisionPropertyPath = verEntCfg.getRevisionNumberPath(); final String revisionPropertyPath = verEntCfg.getRevisionNumberPath();
final String originalIdPropertyName = verEntCfg.getOriginalIdPropName(); final String originalIdPropertyName = verEntCfg.getOriginalIdPropName();
final String eeOriginalIdPropertyPath = MIDDLE_ENTITY_ALIAS + "." + originalIdPropertyName; final String eeOriginalIdPropertyPath = MIDDLE_ENTITY_ALIAS + "." + originalIdPropertyName;
final String revisionTypePropName = getElementRevisionTypePath(); final String revisionTypePropName = getRevisionTypePath();
// (selecting e entities at revision :revision) // (selecting e entities at revision :revision)
// --> based on auditStrategy (see above) // --> based on auditStrategy (see above)
auditStrategy.addEntityAtRevisionRestriction( auditStrategy.addEntityAtRevisionRestriction(
@ -149,7 +149,7 @@ public final class TwoEntityQueryGenerator extends AbstractRelationQueryGenerato
rootParameters.addWhereWithNamedParam( revisionTypePropName, "!=", DEL_REVISION_TYPE_PARAMETER ); rootParameters.addWhereWithNamedParam( revisionTypePropName, "!=", DEL_REVISION_TYPE_PARAMETER );
// e.revision_type != DEL // e.revision_type != DEL
rootParameters.addWhereWithNamedParam( rootParameters.addWhereWithNamedParam(
REFERENCED_ENTITY_ALIAS + "." + getKeyRevisionTypePath(), REFERENCED_ENTITY_ALIAS + "." + revisionTypePropName,
false, false,
"!=", "!=",
DEL_REVISION_TYPE_PARAMETER DEL_REVISION_TYPE_PARAMETER
@ -169,7 +169,7 @@ public final class TwoEntityQueryGenerator extends AbstractRelationQueryGenerato
// Restrictions to match all rows deleted at exactly given revision. // Restrictions to match all rows deleted at exactly given revision.
final Parameters removed = disjoint.addSubParameters( "and" ); final Parameters removed = disjoint.addSubParameters( "and" );
final String revisionPropertyPath = verEntCfg.getRevisionNumberPath(); final String revisionPropertyPath = verEntCfg.getRevisionNumberPath();
final String revisionTypePropName = getElementRevisionTypePath(); final String revisionTypePropName = getRevisionTypePath();
// Excluding current revision, because we need to match data valid at the previous one. // Excluding current revision, because we need to match data valid at the previous one.
createValidDataRestrictions( createValidDataRestrictions(
globalCfg, globalCfg,
@ -194,7 +194,7 @@ public final class TwoEntityQueryGenerator extends AbstractRelationQueryGenerato
removed.addWhereWithNamedParam( revisionTypePropName, "=", DEL_REVISION_TYPE_PARAMETER ); removed.addWhereWithNamedParam( revisionTypePropName, "=", DEL_REVISION_TYPE_PARAMETER );
// e.revision_type = DEL // e.revision_type = DEL
removed.addWhereWithNamedParam( removed.addWhereWithNamedParam(
REFERENCED_ENTITY_ALIAS + "." + getKeyRevisionTypePath(), REFERENCED_ENTITY_ALIAS + "." + revisionTypePropName,
false, false,
"=", "=",
DEL_REVISION_TYPE_PARAMETER DEL_REVISION_TYPE_PARAMETER

View File

@ -19,6 +19,8 @@ import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.Priority;
import org.junit.Test; import org.junit.Test;
import org.hibernate.testing.FailureExpected;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.transaction.TransactionUtil; import org.hibernate.testing.transaction.TransactionUtil;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -27,6 +29,7 @@ import static org.junit.Assert.assertNotNull;
/** /**
* @author Chris Cranford * @author Chris Cranford
*/ */
@TestForIssue(jiraKey = "HHH-11841")
public class EntityMapCompositeElementTest extends BaseEnversJPAFunctionalTestCase { public class EntityMapCompositeElementTest extends BaseEnversJPAFunctionalTestCase {
private Category category; private Category category;
@ -51,6 +54,7 @@ public class EntityMapCompositeElementTest extends BaseEnversJPAFunctionalTestCa
} }
@Test @Test
@FailureExpected(jiraKey = "HHH-11841", message = "Reverted fix in HHH-12018 and will be fixed in HHH-12043")
public void testRevisionHistory() { public void testRevisionHistory() {
final AuditReader reader = getAuditReader(); final AuditReader reader = getAuditReader();