HHH-11886 - Elaborate Envers documentation and switch to actual source code examples
Migrate code snippets to test cases for Join relations queries with multiple predicates
This commit is contained in:
parent
742d8be69c
commit
ab98bcbe9b
|
@ -997,7 +997,7 @@ include::{sourcedir}/QueryAuditTest.java[tags=envers-querying-entity-relation-le
|
||||||
|
|
||||||
Like any other query, constraints may be added to restrict the results.
|
Like any other query, constraints may be added to restrict the results.
|
||||||
|
|
||||||
For example, to find all `Customers` entities whose addresses are in `România`,
|
For example, to find a `Customers` entities at a given revision whose addresses are in `România`,
|
||||||
you can use the following query:
|
you can use the following query:
|
||||||
|
|
||||||
[[envers-querying-entity-relation-join-restriction]]
|
[[envers-querying-entity-relation-join-restriction]]
|
||||||
|
@ -1016,8 +1016,8 @@ include::{extrasdir}/envers-querying-entity-relation-join-restriction.sql[]
|
||||||
|
|
||||||
It is also possible to traverse beyond the first relation in an entity graph.
|
It is also possible to traverse beyond the first relation in an entity graph.
|
||||||
|
|
||||||
For example, to find all `Customer` entities
|
For example, to find all `Customer` entities at a given revision
|
||||||
where the country entity belonging to the address attribute is `România`:
|
with the country attribute of the address property being `România`:
|
||||||
|
|
||||||
[[envers-querying-entity-relation-nested-join-restriction]]
|
[[envers-querying-entity-relation-nested-join-restriction]]
|
||||||
.Filtering a nested join relation with a WHERE clause predicate
|
.Filtering a nested join relation with a WHERE clause predicate
|
||||||
|
@ -1033,63 +1033,78 @@ include::{extrasdir}/envers-querying-entity-relation-nested-join-restriction.sql
|
||||||
----
|
----
|
||||||
====
|
====
|
||||||
|
|
||||||
Complex constraints may also be added that are applicable to properties of nested relations or the base query entity or
|
Constraints may also be added to the properties of nested joined relations, such as testing for `null`.
|
||||||
relation state, such as testing for `null`. For example, the following query illustrates how to find all `Car` entities where
|
|
||||||
the owner's age is `20` or that the car has _no_ owner:
|
|
||||||
|
|
||||||
[source,java]
|
For example, the following query illustrates how to find all `Customer` entities at a given revision
|
||||||
|
having the `address` in `Cluj-Napoca` or the `address` does _not_ have any country entity reference:
|
||||||
|
|
||||||
|
[[envers-querying-entity-relation-join-multiple-restrictions]]
|
||||||
|
.Filtering a join relation using multiple predicates
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
----
|
----
|
||||||
AuditQuery query = getAuditReader().createQuery()
|
include::{sourcedir}/QueryAuditAdressCountryTest.java[tags=envers-querying-entity-relation-join-multiple-restrictions]
|
||||||
.forEntitiesAtRevision( Car.class, 1 )
|
|
||||||
.traverseRelation( "owner", JoinType.LEFT, "p" )
|
|
||||||
.up()
|
|
||||||
.add(
|
|
||||||
AuditEntity.or(
|
|
||||||
AuditEntity.property( "p", "age" ).eq( 20 ),
|
|
||||||
AuditEntity.relatedId( "owner" ).eq( null )
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.addOrder( AuditEntity.property( "make" ).asc() );
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
[source, SQL, indent=0]
|
||||||
|
----
|
||||||
|
include::{extrasdir}/envers-querying-entity-relation-join-multiple-restrictions.sql[]
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
[NOTE]
|
[NOTE]
|
||||||
====
|
====
|
||||||
Queries can use the `up` method to navigate back up the entity graph.
|
Queries can use the `up` method to navigate back up the entity graph.
|
||||||
====
|
====
|
||||||
|
|
||||||
Disjunction criterion may also be applied to relation join queries. For example, the following query will find all
|
Disjunction criterion may also be applied to relation join queries.
|
||||||
`Car` entities where the owner's age is `20` or that the owner lives at an address where the street number equals `1234`:
|
|
||||||
|
|
||||||
[source,java]
|
For example, the following query will find all `Customer` entities at a given revision
|
||||||
|
where the country name is `România` or that the `Customer` lives in `Cluj-Napoca`:
|
||||||
|
|
||||||
|
[[envers-querying-entity-relation-nested-join-multiple-restrictions]]
|
||||||
|
.Filtering a nested join relation using multiple predicates
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
----
|
----
|
||||||
AuditQuery query = getAuditReader().createQuery()
|
include::{sourcedir}/QueryAuditAdressCountryTest.java[tags=envers-querying-entity-relation-nested-join-multiple-restrictions]
|
||||||
.forEntitiesAtRevision( Car.class, 1 )
|
|
||||||
.traverseRelation( "owner", JoinType.INNER, "p" )
|
|
||||||
.traverseRelation( "address", JoinType.INNER, "a" )
|
|
||||||
.up()
|
|
||||||
.up()
|
|
||||||
.add(
|
|
||||||
AuditEntity.disjunction()
|
|
||||||
.add( AuditEntity.property( "p", "age" ).eq( 20 ) )
|
|
||||||
.add( AuditEntity.property( "a", "streetNumber" ).eq( 1234 )
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.addOrder( AuditEntity.property( "make" ).asc() );
|
|
||||||
----
|
----
|
||||||
|
|
||||||
Lastly, this example illustrates how related entity properties can be compared as a constraint. This query shows how to
|
[source, SQL, indent=0]
|
||||||
find the `Car` entities where the owner's `age` equals the `streetNumber` of where the owner lives:
|
----
|
||||||
|
include::{extrasdir}/envers-querying-entity-relation-nested-join-multiple-restrictions.sql[]
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
[source,java]
|
Lastly, this example illustrates how related entity properties can be compared in a single constraint.
|
||||||
|
|
||||||
|
Assuming, the `Customer` and the `Address` were previously changed as follows:
|
||||||
|
|
||||||
|
[[envers-querying-entity-relation-nested-join-multiple-restrictions-combined-entities]]
|
||||||
|
.Changing the `Address` to match the `Country` name
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
----
|
----
|
||||||
AuditQuery query = getAuditReader().createQuery()
|
include::{sourcedir}/QueryAuditAdressCountryTest.java[tags=envers-querying-entity-relation-nested-join-multiple-restrictions-combined-entities]
|
||||||
.forEntitiesAtRevision( Car.class, 1 )
|
|
||||||
.traverseRelation( "owner", JoinType.INNER, "p" )
|
|
||||||
.traverseRelation( "address", JoinType.INNER, "a" )
|
|
||||||
.up()
|
|
||||||
.up()
|
|
||||||
.add( AuditEntity.property( "p", "age" ).eqProperty( "a", "streetNumber" ) );
|
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
The following query shows how to find the `Customer` entities
|
||||||
|
where the `city` property of the `address` attribute equals the `name` of the associated `country` attribute.
|
||||||
|
|
||||||
|
[[envers-querying-entity-relation-nested-join-multiple-restrictions-combined]]
|
||||||
|
.Filtering a nested join relation using multiple predicates
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
include::{sourcedir}/QueryAuditAdressCountryTest.java[tags=envers-querying-entity-relation-nested-join-multiple-restrictions-combined]
|
||||||
|
----
|
||||||
|
|
||||||
|
[source, SQL, indent=0]
|
||||||
|
----
|
||||||
|
include::{extrasdir}/envers-querying-entity-relation-nested-join-multiple-restrictions-combined.sql[]
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
[[envers-conditional-auditing]]
|
[[envers-conditional-auditing]]
|
||||||
=== Conditional auditing
|
=== Conditional auditing
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
select
|
||||||
|
c.id as id1_5_,
|
||||||
|
c.REV as REV2_5_,
|
||||||
|
c.REVTYPE as REVTYPE3_5_,
|
||||||
|
c.REVEND as REVEND4_5_,
|
||||||
|
c.created_on as created_5_5_,
|
||||||
|
c.firstName as firstNam6_5_,
|
||||||
|
c.lastName as lastName7_5_,
|
||||||
|
c.address_id as address_8_5_
|
||||||
|
from
|
||||||
|
Customer_AUD c
|
||||||
|
left outer join
|
||||||
|
Address_AUD a
|
||||||
|
on (
|
||||||
|
c.address_id=a.id
|
||||||
|
or (
|
||||||
|
c.address_id is null
|
||||||
|
)
|
||||||
|
and (
|
||||||
|
a.id is null
|
||||||
|
)
|
||||||
|
)
|
||||||
|
where
|
||||||
|
c.REV<=?
|
||||||
|
and c.REVTYPE<>?
|
||||||
|
and (
|
||||||
|
c.REVEND>?
|
||||||
|
or c.REVEND is null
|
||||||
|
)
|
||||||
|
and (
|
||||||
|
a.REV is null
|
||||||
|
or a.REV<=?
|
||||||
|
and (
|
||||||
|
a.REVEND>?
|
||||||
|
or a.REVEND is null
|
||||||
|
)
|
||||||
|
)
|
||||||
|
and (
|
||||||
|
a.city=?
|
||||||
|
or a.country_id is null
|
||||||
|
)
|
||||||
|
|
||||||
|
-- binding parameter [1] as [INTEGER] - [1]
|
||||||
|
-- binding parameter [2] as [INTEGER] - [2]
|
||||||
|
-- binding parameter [3] as [INTEGER] - [1]
|
||||||
|
-- binding parameter [4] as [INTEGER] - [1]
|
||||||
|
-- binding parameter [5] as [INTEGER] - [1]
|
||||||
|
-- binding parameter [6] as [VARCHAR] - [Cluj-Napoca]
|
|
@ -0,0 +1,59 @@
|
||||||
|
select
|
||||||
|
cu.id as id1_5_,
|
||||||
|
cu.REV as REV2_5_,
|
||||||
|
cu.REVTYPE as REVTYPE3_5_,
|
||||||
|
cu.REVEND as REVEND4_5_,
|
||||||
|
cu.created_on as created_5_5_,
|
||||||
|
cu.firstName as firstNam6_5_,
|
||||||
|
cu.lastName as lastName7_5_,
|
||||||
|
cu.address_id as address_8_5_
|
||||||
|
from
|
||||||
|
Customer_AUD cu
|
||||||
|
inner join
|
||||||
|
Address_AUD a
|
||||||
|
on (
|
||||||
|
cu.address_id=a.id
|
||||||
|
or (
|
||||||
|
cu.address_id is null
|
||||||
|
)
|
||||||
|
and (
|
||||||
|
a.id is null
|
||||||
|
)
|
||||||
|
)
|
||||||
|
inner join
|
||||||
|
Country_AUD cr
|
||||||
|
on (
|
||||||
|
a.country_id=cr.id
|
||||||
|
or (
|
||||||
|
a.country_id is null
|
||||||
|
)
|
||||||
|
and (
|
||||||
|
cr.id is null
|
||||||
|
)
|
||||||
|
)
|
||||||
|
where
|
||||||
|
cu.REV<=?
|
||||||
|
and cu.REVTYPE<>?
|
||||||
|
and a.city=cr.name
|
||||||
|
and (
|
||||||
|
cu.REVEND>?
|
||||||
|
or cu.REVEND is null
|
||||||
|
)
|
||||||
|
and a.REV<=?
|
||||||
|
and (
|
||||||
|
a.REVEND>?
|
||||||
|
or a.REVEND is null
|
||||||
|
)
|
||||||
|
and cr.REV<=?
|
||||||
|
and (
|
||||||
|
cr.REVEND>?
|
||||||
|
or cr.REVEND is null
|
||||||
|
)
|
||||||
|
|
||||||
|
-- binding parameter [1] as [INTEGER] - [2]
|
||||||
|
-- binding parameter [2] as [INTEGER] - [2]
|
||||||
|
-- binding parameter [3] as [INTEGER] - [2]
|
||||||
|
-- binding parameter [4] as [INTEGER] - [2]
|
||||||
|
-- binding parameter [5] as [INTEGER] - [2]
|
||||||
|
-- binding parameter [6] as [INTEGER] - [2]
|
||||||
|
-- binding parameter [7] as [INTEGER] - [2]
|
|
@ -0,0 +1,66 @@
|
||||||
|
select
|
||||||
|
cu.id as id1_5_,
|
||||||
|
cu.REV as REV2_5_,
|
||||||
|
cu.REVTYPE as REVTYPE3_5_,
|
||||||
|
cu.REVEND as REVEND4_5_,
|
||||||
|
cu.created_on as created_5_5_,
|
||||||
|
cu.firstName as firstNam6_5_,
|
||||||
|
cu.lastName as lastName7_5_,
|
||||||
|
cu.address_id as address_8_5_
|
||||||
|
from
|
||||||
|
Customer_AUD cu
|
||||||
|
inner join
|
||||||
|
Address_AUD a
|
||||||
|
on (
|
||||||
|
cu.address_id=a.id
|
||||||
|
or (
|
||||||
|
cu.address_id is null
|
||||||
|
)
|
||||||
|
and (
|
||||||
|
a.id is null
|
||||||
|
)
|
||||||
|
)
|
||||||
|
inner join
|
||||||
|
Country_AUD co
|
||||||
|
on (
|
||||||
|
a.country_id=co.id
|
||||||
|
or (
|
||||||
|
a.country_id is null
|
||||||
|
)
|
||||||
|
and (
|
||||||
|
co.id is null
|
||||||
|
)
|
||||||
|
)
|
||||||
|
where
|
||||||
|
cu.REV<=?
|
||||||
|
and cu.REVTYPE<>?
|
||||||
|
and (
|
||||||
|
cu.REVEND>?
|
||||||
|
or cu.REVEND is null
|
||||||
|
)
|
||||||
|
and (
|
||||||
|
a.city=?
|
||||||
|
or co.name=?
|
||||||
|
)
|
||||||
|
and a.REV<=?
|
||||||
|
and (
|
||||||
|
a.REVEND>?
|
||||||
|
or a.REVEND is null
|
||||||
|
)
|
||||||
|
and co.REV<=?
|
||||||
|
and (
|
||||||
|
co.REVEND>?
|
||||||
|
or co.REVEND is null
|
||||||
|
)
|
||||||
|
order by
|
||||||
|
cu.created_on asc
|
||||||
|
|
||||||
|
-- binding parameter [1] as [INTEGER] - [1]
|
||||||
|
-- binding parameter [2] as [INTEGER] - [2]
|
||||||
|
-- binding parameter [3] as [INTEGER] - [1]
|
||||||
|
-- binding parameter [4] as [VARCHAR] - [Cluj-Napoca]
|
||||||
|
-- binding parameter [5] as [VARCHAR] - [România]
|
||||||
|
-- binding parameter [6] as [INTEGER] - [1]
|
||||||
|
-- binding parameter [7] as [INTEGER] - [1]
|
||||||
|
-- binding parameter [8] as [INTEGER] - [1]
|
||||||
|
-- binding parameter [9] as [INTEGER] - [1]
|
|
@ -98,6 +98,7 @@ public class ManyToManyUnidirectionalTest extends BaseEntityManagerFunctionalTes
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue
|
@GeneratedValue
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||||
private List<Address> addresses = new ArrayList<>();
|
private List<Address> addresses = new ArrayList<>();
|
||||||
|
|
||||||
|
|
|
@ -30,10 +30,12 @@ import org.hibernate.envers.query.AuditQuery;
|
||||||
import org.hibernate.envers.strategy.ValidityAuditStrategy;
|
import org.hibernate.envers.strategy.ValidityAuditStrategy;
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
|
||||||
|
import org.hibernate.test.legacy.Custom;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
|
@ -82,35 +84,104 @@ public class QueryAuditAdressCountryTest extends BaseEntityManagerFunctionalTest
|
||||||
entityManager.persist( customer );
|
entityManager.persist( customer );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
|
||||||
Customer customer = entityManager.find( Customer.class, 1L );
|
|
||||||
customer.setLastName( "Doe Jr." );
|
|
||||||
} );
|
|
||||||
|
|
||||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
|
||||||
Customer customer = entityManager.getReference( Customer.class, 1L );
|
|
||||||
entityManager.remove( customer );
|
|
||||||
} );
|
|
||||||
|
|
||||||
List<Number> revisions = doInJPA( this::entityManagerFactory, entityManager -> {
|
|
||||||
return AuditReaderFactory.get( entityManager ).getRevisions(
|
|
||||||
Customer.class,
|
|
||||||
1L
|
|
||||||
);
|
|
||||||
} );
|
|
||||||
|
|
||||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
//tag::envers-querying-entity-relation-nested-join-restriction[]
|
//tag::envers-querying-entity-relation-nested-join-restriction[]
|
||||||
Customer customer = (Customer) AuditReaderFactory
|
List<Customer> customers = AuditReaderFactory
|
||||||
.get( entityManager )
|
.get( entityManager )
|
||||||
.createQuery()
|
.createQuery()
|
||||||
.forEntitiesAtRevision( Customer.class, 1 )
|
.forEntitiesAtRevision( Customer.class, 1 )
|
||||||
.traverseRelation( "address", JoinType.INNER )
|
.traverseRelation( "address", JoinType.INNER )
|
||||||
.traverseRelation( "country", JoinType.INNER )
|
.traverseRelation( "country", JoinType.INNER )
|
||||||
.add( AuditEntity.property( "name" ).eq( "România" ) )
|
.add( AuditEntity.property( "name" ).eq( "România" ) )
|
||||||
.getSingleResult();
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 1, customers.size() );
|
||||||
//end::envers-querying-entity-relation-nested-join-restriction[]
|
//end::envers-querying-entity-relation-nested-join-restriction[]
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
//tag::envers-querying-entity-relation-join-multiple-restrictions[]
|
||||||
|
List<Customer> customers = AuditReaderFactory
|
||||||
|
.get( entityManager )
|
||||||
|
.createQuery()
|
||||||
|
.forEntitiesAtRevision( Customer.class, 1 )
|
||||||
|
.traverseRelation( "address", JoinType.LEFT, "a" )
|
||||||
|
.add(
|
||||||
|
AuditEntity.or(
|
||||||
|
AuditEntity.property( "a", "city" ).eq( "Cluj-Napoca" ),
|
||||||
|
AuditEntity.relatedId( "country" ).eq( null )
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.getResultList();
|
||||||
|
//end::envers-querying-entity-relation-join-multiple-restrictions[]
|
||||||
|
|
||||||
|
assertEquals( 1, customers.size() );
|
||||||
|
} );
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
//tag::envers-querying-entity-relation-nested-join-multiple-restrictions[]
|
||||||
|
List<Customer> customers = AuditReaderFactory
|
||||||
|
.get( entityManager )
|
||||||
|
.createQuery()
|
||||||
|
.forEntitiesAtRevision( Customer.class, 1 )
|
||||||
|
.traverseRelation( "address", JoinType.INNER, "a" )
|
||||||
|
.traverseRelation( "country", JoinType.INNER, "cn" )
|
||||||
|
.up()
|
||||||
|
.up()
|
||||||
|
.add(
|
||||||
|
AuditEntity.disjunction()
|
||||||
|
.add( AuditEntity.property( "a", "city" ).eq( "Cluj-Napoca" ) )
|
||||||
|
.add( AuditEntity.property( "cn", "name" ).eq( "România" ) )
|
||||||
|
)
|
||||||
|
.addOrder( AuditEntity.property( "createdOn" ).asc() )
|
||||||
|
.getResultList();
|
||||||
|
//end::envers-querying-entity-relation-nested-join-multiple-restrictions[]
|
||||||
|
|
||||||
|
assertEquals( 1, customers.size() );
|
||||||
|
} );
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
//tag::envers-querying-entity-relation-nested-join-multiple-restrictions-combined-entities[]
|
||||||
|
Customer customer = entityManager.createQuery(
|
||||||
|
"select c " +
|
||||||
|
"from Customer c " +
|
||||||
|
"join fetch c.address a " +
|
||||||
|
"join fetch a.country " +
|
||||||
|
"where c.id = :id", Customer.class )
|
||||||
|
.setParameter( "id", 1L )
|
||||||
|
.getSingleResult();
|
||||||
|
|
||||||
|
customer.setLastName( "Doe Sr." );
|
||||||
|
|
||||||
|
customer.getAddress().setCity(
|
||||||
|
customer.getAddress().getCountry().getName()
|
||||||
|
);
|
||||||
|
//end::envers-querying-entity-relation-nested-join-multiple-restrictions-combined-entities[]
|
||||||
|
} );
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
|
||||||
|
//tag::envers-querying-entity-relation-nested-join-multiple-restrictions-combined[]
|
||||||
|
List<Number> revisions = AuditReaderFactory.get( entityManager ).getRevisions(
|
||||||
|
Customer.class,
|
||||||
|
1L
|
||||||
|
);
|
||||||
|
|
||||||
|
List<Customer> customers = AuditReaderFactory
|
||||||
|
.get( entityManager )
|
||||||
|
.createQuery()
|
||||||
|
.forEntitiesAtRevision( Customer.class, revisions.get( revisions.size() - 1 ) )
|
||||||
|
.traverseRelation( "address", JoinType.INNER, "a" )
|
||||||
|
.traverseRelation( "country", JoinType.INNER, "cn" )
|
||||||
|
.up()
|
||||||
|
.up()
|
||||||
|
.add( AuditEntity.property( "a", "city" ).eqProperty( "cn", "name" ) )
|
||||||
|
.getResultList();
|
||||||
|
//end::envers-querying-entity-relation-nested-join-multiple-restrictions-combined[]
|
||||||
|
|
||||||
|
assertEquals( 1, customers.size() );
|
||||||
|
} );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Audited
|
@Audited
|
||||||
|
|
|
@ -250,14 +250,16 @@ public class QueryAuditTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
//tag::envers-querying-entity-relation-join-restriction[]
|
//tag::envers-querying-entity-relation-join-restriction[]
|
||||||
Customer customer = (Customer) AuditReaderFactory
|
List<Customer> customers = AuditReaderFactory
|
||||||
.get( entityManager )
|
.get( entityManager )
|
||||||
.createQuery()
|
.createQuery()
|
||||||
.forEntitiesAtRevision( Customer.class, 1 )
|
.forEntitiesAtRevision( Customer.class, 1 )
|
||||||
.traverseRelation( "address", JoinType.INNER )
|
.traverseRelation( "address", JoinType.INNER )
|
||||||
.add( AuditEntity.property( "country" ).eq( "România" ) )
|
.add( AuditEntity.property( "country" ).eq( "România" ) )
|
||||||
.getSingleResult();
|
.getResultList();
|
||||||
//end::envers-querying-entity-relation-join-restriction[]
|
//end::envers-querying-entity-relation-join-restriction[]
|
||||||
|
|
||||||
|
assertEquals( 1, customers.size() );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue