diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/JoinedInheritancePropertyJoinTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/JoinedInheritancePropertyJoinTest.java new file mode 100644 index 0000000000..05f546bbe6 --- /dev/null +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/JoinedInheritancePropertyJoinTest.java @@ -0,0 +1,194 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.envers.test.integration.query; + +import java.util.List; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.OneToOne; +import javax.persistence.criteria.JoinType; + +import org.hibernate.envers.Audited; +import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; +import org.hibernate.envers.test.Priority; +import org.junit.Test; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.transaction.TransactionUtil; + +import static org.junit.Assert.assertEquals; + +/** + * @author Chris Cranford + */ +@TestForIssue(jiraKey = "HHH-11416") +public class JoinedInheritancePropertyJoinTest extends BaseEnversJPAFunctionalTestCase { + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { EntityA.class, EntityB.class, EntityC.class }; + } + + @Test + @Priority(10) + public void initData() { + TransactionUtil.doInJPA( this::entityManagerFactory, entityManager -> { + final EntityC c1 = new EntityC(); + c1.setId( 1 ); + c1.setName( "c1" ); + c1.setFoo( "foo" ); + c1.setPropB( "propB" ); + c1.setPropC( "propC" ); + entityManager.persist( c1 ); + + final EntityA a1 = new EntityA(); + a1.setId( 1 ); + a1.setRelationToC( c1 ); + a1.setPropA( "propC" ); + entityManager.persist( a1 ); + } ); + } + + @Test + public void testAuditQueryWithJoinedInheritanceUnrelatedPropertyJoin() { + // The problem is that this query succeeds on DefaultAuditStrategy, fails on ValidityAuditStrategy + // + // ValidityAuditStrategy + // --------------------- + // select + // joinedinhe0_.id as id1_1_, + // joinedinhe0_.REV as REV2_1_, + // joinedinhe0_.REVTYPE as REVTYPE3_1_, + // joinedinhe0_.REVEND as REVEND4_1_, + // joinedinhe0_.relationToC_id as relation5_1_ + // from + // EntityA_AUD joinedinhe0_ + // inner join EntityC_AUD joinedinhe1_ + // on (joinedinhe0_.relationToC_id=joinedinhe1_.id or (joinedinhe0_.relationToC_id is null) + // and (joinedinhe1_.id is null)) + // where + // joinedinhe0_.REV<=? + // and + // joinedinhe0_.REVTYPE<>? + // and + // (joinedinhe0_.REVEND>? or joinedinhe0_.REVEND is null) + // and + // joinedinhe1_.REV<=? + // and + // (joinedinhe1_1_.REVEND>? or joinedinhe1_1_.REVEND is null) + // + // Error: SQL Error: 42122, SQLState: 42S22 + // Column "JOINEDINHE1_1_.REVEND" not found + // + List results = getAuditReader().createQuery().forEntitiesAtRevision( EntityA.class, 1 ) + .traverseRelation( "relationToC", JoinType.INNER ) + .getResultList(); + assertEquals( 1, results.size() ); + } + + @Test + public void testHibernateUnrelatedPropertyQuery() { + final String queryString = "FROM EntityA a Inner Join EntityC c ON a.propA = c.propC Where c.propB = :propB"; + TransactionUtil.doInJPA( this::entityManagerFactory, entityManager -> { + List results = entityManager.createQuery( queryString ).setParameter( "propB", "propB" ).getResultList(); + assertEquals( 1, results.size() ); + } ); + } + + @Entity(name = "EntityA") + @Audited + public static class EntityA { + @Id + private Integer id; + private String propA; + @OneToOne + private EntityC relationToC; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getPropA() { + return propA; + } + + public void setPropA(String propA) { + this.propA = propA; + } + + public EntityC getRelationToC() { + return relationToC; + } + + public void setRelationToC(EntityC relationToC) { + this.relationToC = relationToC; + } + } + + @Entity(name = "EntityB") + @Audited + @Inheritance(strategy = InheritanceType.JOINED) + public static class EntityB { + @Id + private Integer id; + private String name; + private String propB; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPropB() { + return propB; + } + + public void setPropB(String propB) { + this.propB = propB; + } + } + + @Entity(name = "EntityC") + @Audited + public static class EntityC extends EntityB { + private String foo; + private String propC; + + public String getFoo() { + return foo; + } + + public void setFoo(String foo) { + this.foo = foo; + } + + public String getPropC() { + return propC; + } + + public void setPropC(String propC) { + this.propC = propC; + } + } +}