HHH-12349 - User Guide documentation for @Filter is too verbose

This commit is contained in:
Vlad Mihalcea 2018-07-11 17:42:05 +03:00
parent b09fbb431d
commit 5e6298d2f9
12 changed files with 538 additions and 433 deletions

View File

@ -1829,19 +1829,40 @@ include::{sourcedir}/basic/WhereJoinTableTest.java[tags=mapping-where-join-table
[[mapping-column-filter]]
==== `@Filter`
The `@Filter` annotation is another way to filter out entities or collections using custom SQL criteria, for both entities and collections.
The `@Filter` annotation is another way to filter out entities or collections using custom SQL criteria.
Unlike the `@Where` annotation, `@Filter` allows you to parameterize the filter clause at runtime.
[[mapping-filter-example]]
.`@Filter` mapping usage
Now, considering we have the following `Account` entity:
[[mapping-filter-account-example]]
.`@Filter` mapping entity-level usage
====
[source, JAVA, indent=0]
----
include::{sourcedir}/basic/FilterTest.java[tags=mapping-filter-example]
include::{sourcedir}/basic/FilterTest.java[tags=mapping-filter-Account-example]
----
====
If the database contains the following entities:
[NOTE]
====
Notice that the `active` property is mapped to the `active_status` column.
This mapping was done to show you that the `@Filter` condition uses a SQL condition, and not a JPQL filtering criteria.
====
As already explained, we can also apply the `@Filter` annotation for collections as illustrated by the `Client` entity:
[[mapping-filter-client-example]]
.`@Filter` mapping collection-level usage
====
[source, JAVA, indent=0]
----
include::{sourcedir}/basic/FilterTest.java[tags=mapping-filter-Client-example]
----
====
If we persist a `Client` with three associated `Account` entities,
Hibernate will execute the following SQL statements:
[[mapping-filter-persistence-example]]
.Persisting and fetching entities with a `@Filter` mapping
@ -1858,6 +1879,21 @@ include::{extrasdir}/basic/mapping-filter-persistence-example.sql[]
====
By default, without explicitly enabling the filter, Hibernate is going to fetch all `Account` entities.
[[mapping-no-filter-entity-query-example]]
.Query entities mapped without activating the `@Filter`
====
[source, JAVA, indent=0]
----
include::{sourcedir}/basic/FilterTest.java[tags=mapping-no-filter-entity-query-example]
----
[source, SQL, indent=0]
----
include::{extrasdir}/basic/mapping-no-filter-entity-query-example.sql[]
----
====
If the filter is enabled and the filter parameter value is provided,
then Hibernate is going to apply the filtering criteria to the associated `Account` entities.
@ -1878,6 +1914,7 @@ include::{extrasdir}/basic/mapping-filter-entity-query-example.sql[]
[IMPORTANT]
====
Filters apply to entity queries, but not to direct fetching.
Therefore, in the following example, the filter is not taken into consideration when fetching an entity from the Persistence Context.
[[mapping-filter-entity-example]]
@ -1896,7 +1933,22 @@ As you can see from the example above, contrary to an entity query, the filter d
====
Just like with entity queries, collections can be filtered as well, but only if the filter is explicitly enabled on the currently running Hibernate `Session`.
This way, when fetching the `accounts` collections, Hibernate is going to apply the `@Filter` clause filtering criteria to the associated collection entries.
[[mapping-no-filter-collection-query-example]]
.Traversing collections without activating the `@Filter`
====
[source, JAVA, indent=0]
----
include::{sourcedir}/basic/FilterTest.java[tags=mapping-no-filter-collection-query-example]
----
[source, SQL, indent=0]
----
include::{extrasdir}/basic/mapping-no-filter-collection-query-example.sql[]
----
====
When activating the `@Filter` and fetching the `accounts` collections, Hibernate is going to apply the filter condition to the associated collection entries.
[[mapping-filter-collection-query-example]]
.Traversing collections mapped with `@Filter`
@ -1922,7 +1974,7 @@ The main advantage of `@Filter` over the `@Where` clause is that the filtering c
It's not possible to combine the `@Filter` and `@Cache` collection annotations.
This limitation is due to ensuring consistency and because the filtering information is not stored in the second-level cache.
If caching was allowed for a currently filtered collection, then the second-level cache would store only a subset of the whole collection.
If caching were allowed for a currently filtered collection, then the second-level cache would store only a subset of the whole collection.
Afterward, every other Session will get the filtered collection from the cache, even if the Session-level filters have not been explicitly activated.
For this reason, the second-level collection cache is limited to storing whole collections, and not subsets.
@ -1934,7 +1986,7 @@ For this reason, the second-level collection cache is limited to storing whole c
When using the `@Filter` annotation with collections, the filtering is done against the child entries (entities or embeddables).
However, if you have a link table between the parent entity and the child table, then you need to use the `@FilterJoinTable` to filter child entries according to some column contained in the join table.
The `@FilterJoinTable` annotation can be, therefore, applied to a unidirectional `@OneToMany` collection as illustrate din the following mapping:
The `@FilterJoinTable` annotation can be, therefore, applied to a unidirectional `@OneToMany` collection as illustrated in the following mapping:
[[mapping-filter-join-table-example]]
.`@FilterJoinTable` mapping usage
@ -1945,7 +1997,11 @@ include::{sourcedir}/basic/FilterJoinTableTest.java[tags=mapping-filter-join-tab
----
====
If the database contains the following entities:
The `firstAccounts` filter will allow us to get only the `Account` entities that have the `order_id`
(which tells the position of every entry inside the `accounts` collection)
less than a given number (e.g. `maxOrderId`).
Let's assume our database contains the following entities:
[[mapping-filter-join-table-persistence-example]]
.Persisting and fetching entities with a `@FilterJoinTable` mapping
@ -1961,8 +2017,24 @@ include::{extrasdir}/basic/mapping-filter-join-table-persistence-example.sql[]
----
====
The collections can be filtered if the associated filter is enabled on the currently running Hibernate `Session`.
This way, when fetching the `accounts` collections, Hibernate is going to apply the `@FilterJoinTable` clause filtering criteria to the associated collection entries.
The collections can be filtered only if the associated filter is enabled on the currently running Hibernate `Session`.
[[mapping-no-filter-join-table-collection-query-example]]
.Traversing collections mapped with `@FilterJoinTable` without enabling the filter
====
[source, JAVA, indent=0]
----
include::{sourcedir}/basic/FilterJoinTableTest.java[tags=mapping-no-filter-join-table-collection-query-example]
----
[source, SQL, indent=0]
----
include::{extrasdir}/basic/mapping-no-filter-join-table-collection-query-example.sql[]
----
====
If we enable the filter and set the `maxOrderId` to `1`, when fetching the `accounts` collections, Hibernate is going to apply the `@FilterJoinTable` clause filtering criteria, and we will get just
`2` `Account` entities, with the `order_id` values of `0` and `1`.
[[mapping-filter-join-table-collection-query-example]]
.Traversing collections mapped with `@FilterJoinTable`

View File

@ -1,25 +1,3 @@
SELECT
c.id as id1_1_0_,
c.name as name2_1_0_
FROM
Client c
WHERE
c.id = 1
SELECT
a.id as id1_0_,
a.active as active2_0_,
a.amount as amount3_0_,
a.client_id as client_i6_0_,
a.rate as rate4_0_,
a.account_type as account_5_0_
FROM
Account a
WHERE
a.client_id = 1
-- Activate filter [activeAccount]
SELECT
c.id as id1_1_0_,
c.name as name2_1_0_
@ -30,7 +8,7 @@ WHERE
SELECT
a.id as id1_0_,
a.active as active2_0_,
a.active_status as active2_0_,
a.amount as amount3_0_,
a.client_id as client_i6_0_,
a.rate as rate4_0_,
@ -38,5 +16,5 @@ SELECT
FROM
Account a
WHERE
accounts0_.active = true
accounts0_.active_status = true
and a.client_id = 1

View File

@ -1,6 +1,6 @@
SELECT
a.id as id1_0_0_,
a.active as active2_0_0_,
a.active_status as active2_0_0_,
a.amount as amount3_0_0_,
a.client_id as client_i6_0_0_,
a.rate as rate4_0_0_,
@ -8,9 +8,6 @@ SELECT
c.id as id1_1_1_,
c.name as name2_1_1_
FROM
Account a
LEFT OUTER JOIN
Client c
ON a.client_id=c.id
Account a
WHERE
a.id = 2

View File

@ -1,18 +1,6 @@
SELECT
a.id as id1_0_,
a.active as active2_0_,
a.amount as amount3_0_,
a.client_id as client_i6_0_,
a.rate as rate4_0_,
a.account_type as account_5_0_
FROM
Account a
-- Activate filter [activeAccount]
SELECT
a.id as id1_0_,
a.active as active2_0_,
a.active_status as active2_0_,
a.amount as amount3_0_,
a.client_id as client_i6_0_,
a.rate as rate4_0_,
@ -20,4 +8,4 @@ SELECT
FROM
Account a
WHERE
a.active = true
a.active_status = true

View File

@ -3,7 +3,6 @@ SELECT
ca.accounts_id as accounts2_2_0_,
ca.order_id as order_id3_0_,
a.id as id1_0_1_,
a.active as active2_0_1_,
a.amount as amount3_0_1_,
a.rate as rate4_0_1_,
a.account_type as account_5_0_1_
@ -12,27 +11,6 @@ FROM
INNER JOIN
Account a
ON ca.accounts_id=a.id
WHERE
ca.Client_id = ?
-- binding parameter [1] as [BIGINT] - [1]
-- Activate filter [firstAccounts]
SELECT
ca.Client_id as Client_i1_2_0_,
ca.accounts_id as accounts2_2_0_,
ca.order_id as order_id3_0_,
a.id as id1_0_1_,
a.active as active2_0_1_,
a.amount as amount3_0_1_,
a.rate as rate4_0_1_,
a.account_type as account_5_0_1_
FROM
Client_Account ca
INNER JOIN
Account a
ON ca.accounts_id=a.id
WHERE
ca.order_id <= ?
AND ca.Client_id = ?

View File

@ -1,14 +1,14 @@
INSERT INTO Client (name, id)
VALUES ('John Doe', 1)
INSERT INTO Account (active, amount, client_id, rate, account_type, id)
VALUES (true, 5000.0, 1, 0.0125, 'CREDIT', 1)
INSERT INTO Account (amount, client_id, rate, account_type, id)
VALUES (5000.0, 1, 0.0125, 'CREDIT', 1)
INSERT INTO Account (active, amount, client_id, rate, account_type, id)
VALUES (false, 0.0, 1, 0.0105, 'DEBIT', 2)
INSERT INTO Account (amount, client_id, rate, account_type, id)
VALUES (0.0, 1, 0.0105, 'DEBIT', 2)
INSERT INTO Account (active, amount, client_id, rate, account_type, id)
VALUES (true, 250.0, 1, 0.0105, 'DEBIT', 3)
INSERT INTO Account (amount, client_id, rate, account_type, id)
VALUES (250.0, 1, 0.0105, 'DEBIT', 3)
INSERT INTO Client_Account (Client_id, order_id, accounts_id)
VALUES (1, 0, 1)

View File

@ -1,11 +1,11 @@
INSERT INTO Client (name, id)
VALUES ('John Doe', 1)
INSERT INTO Account (active, amount, client_id, rate, account_type, id)
INSERT INTO Account (active_status, amount, client_id, rate, account_type, id)
VALUES (true, 5000.0, 1, 0.0125, 'CREDIT', 1)
INSERT INTO Account (active, amount, client_id, rate, account_type, id)
INSERT INTO Account (active_status, amount, client_id, rate, account_type, id)
VALUES (false, 0.0, 1, 0.0105, 'DEBIT', 2)
INSERT INTO Account (active, amount, client_id, rate, account_type, id)
INSERT INTO Account (active_status, amount, client_id, rate, account_type, id)
VALUES (true, 250.0, 1, 0.0105, 'DEBIT', 3)

View File

@ -0,0 +1,19 @@
SELECT
c.id as id1_1_0_,
c.name as name2_1_0_
FROM
Client c
WHERE
c.id = 1
SELECT
a.id as id1_0_,
a.active_status as active2_0_,
a.amount as amount3_0_,
a.client_id as client_i6_0_,
a.rate as rate4_0_,
a.account_type as account_5_0_
FROM
Account a
WHERE
a.client_id = 1

View File

@ -0,0 +1,9 @@
SELECT
a.id as id1_0_,
a.active_status as active2_0_,
a.amount as amount3_0_,
a.client_id as client_i6_0_,
a.rate as rate4_0_,
a.account_type as account_5_0_
FROM
Account a

View File

@ -0,0 +1,17 @@
SELECT
ca.Client_id as Client_i1_2_0_,
ca.accounts_id as accounts2_2_0_,
ca.order_id as order_id3_0_,
a.id as id1_0_1_,
a.amount as amount3_0_1_,
a.rate as rate4_0_1_,
a.account_type as account_5_0_1_
FROM
Client_Account ca
INNER JOIN
Account a
ON ca.accounts_id=a.id
WHERE
ca.Client_id = ?
-- binding parameter [1] as [BIGINT] - [1]

View File

@ -8,6 +8,7 @@ package org.hibernate.userguide.mapping.basic;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
@ -35,180 +36,190 @@ import static org.junit.Assert.assertEquals;
*/
public class FilterJoinTableTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Client.class,
Account.class
};
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Client.class,
Account.class
};
}
@Test
public void testLifecycle() {
//tag::mapping-filter-join-table-persistence-example[]
doInJPA( this::entityManagerFactory, entityManager -> {
@Test
public void testLifecycle() {
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::mapping-filter-join-table-persistence-example[]
Client client = new Client()
.setId( 1L )
.setName( "John Doe" );
Client client = new Client();
client.setId( 1L );
client.setName( "John Doe" );
entityManager.persist( client );
client.addAccount(
new Account()
.setId( 1L )
.setType( AccountType.CREDIT )
.setAmount( 5000d )
.setRate( 1.25 / 100 )
);
Account account1 = new Account( );
account1.setId( 1L );
account1.setType( AccountType.CREDIT );
account1.setAmount( 5000d );
account1.setRate( 1.25 / 100 );
account1.setActive( true );
client.getAccounts().add( account1 );
entityManager.persist( account1 );
client.addAccount(
new Account()
.setId( 2L )
.setType( AccountType.DEBIT )
.setAmount( 0d )
.setRate( 1.05 / 100 )
);
Account account2 = new Account( );
account2.setId( 2L );
account2.setType( AccountType.DEBIT );
account2.setAmount( 0d );
account2.setRate( 1.05 / 100 );
account2.setActive( false );
client.getAccounts().add( account2 );
entityManager.persist( account2 );
client.addAccount(
new Account()
.setType( AccountType.DEBIT )
.setId( 3L )
.setAmount( 250d )
.setRate( 1.05 / 100 )
);
Account account3 = new Account( );
account3.setType( AccountType.DEBIT );
account3.setId( 3L );
account3.setAmount( 250d );
account3.setRate( 1.05 / 100 );
account3.setActive( true );
client.getAccounts().add( account3 );
entityManager.persist( account3 );
} );
//end::mapping-filter-join-table-persistence-example[]
entityManager.persist( client );
//end::mapping-filter-join-table-persistence-example[]
} );
//tag::mapping-filter-join-table-collection-query-example[]
doInJPA( this::entityManagerFactory, entityManager -> {
Client client = entityManager.find( Client.class, 1L );
assertEquals( 3, client.getAccounts().size());
} );
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::mapping-no-filter-join-table-collection-query-example[]
Client client = entityManager.find( Client.class, 1L );
doInJPA( this::entityManagerFactory, entityManager -> {
log.infof( "Activate filter [%s]", "firstAccounts");
assertEquals( 3, client.getAccounts().size());
//end::mapping-no-filter-join-table-collection-query-example[]
} );
Client client = entityManager.find( Client.class, 1L );
doInJPA( this::entityManagerFactory, entityManager -> {
log.infof( "Activate filter [%s]", "firstAccounts");
entityManager
.unwrap( Session.class )
.enableFilter( "firstAccounts" )
.setParameter( "maxOrderId", 1);
//tag::mapping-filter-join-table-collection-query-example[]
Client client = entityManager.find( Client.class, 1L );
assertEquals( 2, client.getAccounts().size());
} );
//end::mapping-filter-join-table-collection-query-example[]
}
entityManager
.unwrap( Session.class )
.enableFilter( "firstAccounts" )
.setParameter( "maxOrderId", 1);
//tag::mapping-filter-join-table-example[]
public enum AccountType {
DEBIT,
CREDIT
}
assertEquals( 2, client.getAccounts().size());
//end::mapping-filter-join-table-collection-query-example[]
} );
}
@Entity(name = "Client")
@FilterDef(name="firstAccounts", parameters=@ParamDef( name="maxOrderId", type="int" ) )
@Filter(name="firstAccounts", condition="order_id <= :maxOrderId")
public static class Client {
public enum AccountType {
DEBIT,
CREDIT
}
@Id
private Long id;
//tag::mapping-filter-join-table-example[]
@Entity(name = "Client")
@FilterDef(
name="firstAccounts",
parameters=@ParamDef(
name="maxOrderId",
type="int"
)
)
@Filter(
name="firstAccounts",
condition="order_id <= :maxOrderId"
)
public static class Client {
private String name;
@Id
private Long id;
@OneToMany
@OrderColumn(name = "order_id")
@FilterJoinTable(name="firstAccounts", condition="order_id <= :maxOrderId")
private List<Account> accounts = new ArrayList<>( );
private String name;
//Getters and setters omitted for brevity
@OneToMany(cascade = CascadeType.ALL)
@OrderColumn(name = "order_id")
@FilterJoinTable(
name="firstAccounts",
condition="order_id <= :maxOrderId"
)
private List<Account> accounts = new ArrayList<>( );
//end::mapping-filter-join-table-example[]
public Long getId() {
return id;
}
//Getters and setters omitted for brevity
//end::mapping-filter-join-table-example[]
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Client setId(Long id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Client setName(String name) {
this.name = name;
return this;
}
public List<Account> getAccounts() {
return accounts;
}
//tag::mapping-filter-join-table-example[]
}
public List<Account> getAccounts() {
return accounts;
}
//tag::mapping-filter-join-table-example[]
@Entity(name = "Account")
public static class Account {
public void addAccount(Account account) {
this.accounts.add( account );
}
}
@Id
private Long id;
@Entity(name = "Account")
public static class Account {
@Column(name = "account_type")
@Enumerated(EnumType.STRING)
private AccountType type;
@Id
private Long id;
private Double amount;
@Column(name = "account_type")
@Enumerated(EnumType.STRING)
private AccountType type;
private Double rate;
private Double amount;
private boolean active;
private Double rate;
//Getters and setters omitted for brevity
//Getters and setters omitted for brevity
//end::mapping-filter-join-table-example[]
public Long getId() {
return id;
}
//end::mapping-filter-join-table-example[]
public Long getId() {
return id;
}
public Account setId(Long id) {
this.id = id;
return this;
}
public void setId(Long id) {
this.id = id;
}
public AccountType getType() {
return type;
}
public AccountType getType() {
return type;
}
public Account setType(AccountType type) {
this.type = type;
return this;
}
public void setType(AccountType type) {
this.type = type;
}
public Double getAmount() {
return amount;
}
public Double getAmount() {
return amount;
}
public Account setAmount(Double amount) {
this.amount = amount;
return this;
}
public void setAmount(Double amount) {
this.amount = amount;
}
public Double getRate() {
return rate;
}
public Double getRate() {
return rate;
}
public Account setRate(Double rate) {
this.rate = rate;
return this;
}
public void setRate(Double rate) {
this.rate = rate;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
//tag::mapping-filter-join-table-example[]
}
//end::mapping-filter-join-table-example[]
//tag::mapping-filter-join-table-example[]
}
//end::mapping-filter-join-table-example[]
}

View File

@ -8,10 +8,12 @@ package org.hibernate.userguide.mapping.basic;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.NoResultException;
@ -39,267 +41,301 @@ import static org.junit.Assert.assertNull;
*/
public class FilterTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Client.class,
Account.class
};
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Client.class,
Account.class
};
}
@Test
public void testLifecycle() {
//tag::mapping-filter-persistence-example[]
doInJPA( this::entityManagerFactory, entityManager -> {
@Test
public void testLifecycle() {
doInJPA( this::entityManagerFactory, entityManager -> {
Client client = new Client();
client.setId( 1L );
client.setName( "John Doe" );
entityManager.persist( client );
//tag::mapping-filter-persistence-example[]
Client client = new Client()
.setId( 1L )
.setName( "John Doe" );
Account account1 = new Account( );
account1.setId( 1L );
account1.setType( AccountType.CREDIT );
account1.setAmount( 5000d );
account1.setRate( 1.25 / 100 );
account1.setActive( true );
account1.setClient( client );
client.getAccounts().add( account1 );
entityManager.persist( account1 );
client.addAccount(
new Account()
.setId( 1L )
.setType( AccountType.CREDIT )
.setAmount( 5000d )
.setRate( 1.25 / 100 )
.setActive( true )
);
Account account2 = new Account( );
account2.setId( 2L );
account2.setType( AccountType.DEBIT );
account2.setAmount( 0d );
account2.setRate( 1.05 / 100 );
account2.setActive( false );
account2.setClient( client );
client.getAccounts().add( account2 );
entityManager.persist( account2 );
client.addAccount(
new Account()
.setId( 2L )
.setType( AccountType.DEBIT )
.setAmount( 0d )
.setRate( 1.05 / 100 )
.setActive( false )
);
Account account3 = new Account( );
account3.setType( AccountType.DEBIT );
account3.setId( 3L );
account3.setAmount( 250d );
account3.setRate( 1.05 / 100 );
account3.setActive( true );
account3.setClient( client );
client.getAccounts().add( account3 );
entityManager.persist( account3 );
} );
//end::mapping-filter-persistence-example[]
client.addAccount(
new Account()
.setType( AccountType.DEBIT )
.setId( 3L )
.setAmount( 250d )
.setRate( 1.05 / 100 )
.setActive( true )
);
doInJPA( this::entityManagerFactory, entityManager -> {
log.infof( "Activate filter [%s]", "activeAccount");
entityManager.persist( client );
//end::mapping-filter-persistence-example[]
} );
entityManager
.unwrap( Session.class )
.enableFilter( "activeAccount" )
.setParameter( "active", true);
doInJPA( this::entityManagerFactory, entityManager -> {
log.infof( "Activate filter [%s]", "activeAccount");
Account account1 = entityManager.find( Account.class, 1L );
Account account2 = entityManager.find( Account.class, 2L );
entityManager
.unwrap( Session.class )
.enableFilter( "activeAccount" )
.setParameter( "active", true);
assertNotNull( account1 );
assertNotNull( account2 );
} );
Account account1 = entityManager.find( Account.class, 1L );
Account account2 = entityManager.find( Account.class, 2L );
doInJPA( this::entityManagerFactory, entityManager -> {
log.infof( "Activate filter [%s]", "activeAccount");
assertNotNull( account1 );
assertNotNull( account2 );
} );
entityManager
.unwrap( Session.class )
.enableFilter( "activeAccount" )
.setParameter( "active", true);
doInJPA( this::entityManagerFactory, entityManager -> {
log.infof( "Activate filter [%s]", "activeAccount");
Account account1 = entityManager.createQuery(
"select a from Account a where a.id = :id", Account.class)
.setParameter( "id", 1L )
.getSingleResult();
assertNotNull( account1 );
try {
Account account2 = entityManager.createQuery(
"select a from Account a where a.id = :id", Account.class)
.setParameter( "id", 2L )
.getSingleResult();
}
catch (NoResultException expected) {
}
} );
entityManager
.unwrap( Session.class )
.enableFilter( "activeAccount" )
.setParameter( "active", true);
//tag::mapping-filter-entity-example[]
doInJPA( this::entityManagerFactory, entityManager -> {
log.infof( "Activate filter [%s]", "activeAccount");
Account account1 = entityManager.createQuery(
"select a from Account a where a.id = :id", Account.class)
.setParameter( "id", 1L )
.getSingleResult();
assertNotNull( account1 );
try {
Account account2 = entityManager.createQuery(
"select a from Account a where a.id = :id", Account.class)
.setParameter( "id", 2L )
.getSingleResult();
}
catch (NoResultException expected) {
}
} );
entityManager
.unwrap( Session.class )
.enableFilter( "activeAccount" )
.setParameter( "active", true);
doInJPA( this::entityManagerFactory, entityManager -> {
log.infof( "Activate filter [%s]", "activeAccount");
//tag::mapping-filter-entity-example[]
entityManager
.unwrap( Session.class )
.enableFilter( "activeAccount" )
.setParameter( "active", true);
Account account = entityManager.find( Account.class, 2L );
assertFalse( account.isActive() );
} );
//end::mapping-filter-entity-example[]
Account account = entityManager.find( Account.class, 2L );
// tag::mapping-filter-entity-query-example[]
doInJPA( this::entityManagerFactory, entityManager -> {
List<Account> accounts = entityManager.createQuery(
"select a from Account a", Account.class)
.getResultList();
assertEquals( 3, accounts.size());
} );
assertFalse( account.isActive() );
//end::mapping-filter-entity-example[]
} );
doInJPA( this::entityManagerFactory, entityManager -> {
log.infof( "Activate filter [%s]", "activeAccount");
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::mapping-no-filter-entity-query-example[]
List<Account> accounts = entityManager.createQuery(
"select a from Account a", Account.class)
.getResultList();
entityManager
.unwrap( Session.class )
.enableFilter( "activeAccount" )
.setParameter( "active", true);
assertEquals( 3, accounts.size());
//end::mapping-no-filter-entity-query-example[]
} );
List<Account> accounts = entityManager.createQuery(
"select a from Account a", Account.class)
.getResultList();
assertEquals( 2, accounts.size());
} );
//end::mapping-filter-entity-query-example[]
doInJPA( this::entityManagerFactory, entityManager -> {
log.infof( "Activate filter [%s]", "activeAccount");
//tag::mapping-filter-entity-query-example[]
entityManager
.unwrap( Session.class )
.enableFilter( "activeAccount" )
.setParameter( "active", true);
//tag::mapping-filter-collection-query-example[]
doInJPA( this::entityManagerFactory, entityManager -> {
Client client = entityManager.find( Client.class, 1L );
assertEquals( 3, client.getAccounts().size() );
} );
List<Account> accounts = entityManager.createQuery(
"select a from Account a", Account.class)
.getResultList();
doInJPA( this::entityManagerFactory, entityManager -> {
log.infof( "Activate filter [%s]", "activeAccount");
assertEquals( 2, accounts.size());
//end::mapping-filter-entity-query-example[]
} );
entityManager
.unwrap( Session.class )
.enableFilter( "activeAccount" )
.setParameter( "active", true);
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::mapping-no-filter-collection-query-example[]
Client client = entityManager.find( Client.class, 1L );
Client client = entityManager.find( Client.class, 1L );
assertEquals( 2, client.getAccounts().size() );
} );
//end::mapping-filter-collection-query-example[]
}
assertEquals( 3, client.getAccounts().size() );
//end::mapping-no-filter-collection-query-example[]
} );
//tag::mapping-filter-example[]
public enum AccountType {
DEBIT,
CREDIT
}
doInJPA( this::entityManagerFactory, entityManager -> {
log.infof( "Activate filter [%s]", "activeAccount");
@Entity(name = "Client")
public static class Client {
//tag::mapping-filter-collection-query-example[]
entityManager
.unwrap( Session.class )
.enableFilter( "activeAccount" )
.setParameter( "active", true);
@Id
private Long id;
Client client = entityManager.find( Client.class, 1L );
private String name;
assertEquals( 2, client.getAccounts().size() );
//end::mapping-filter-collection-query-example[]
} );
}
@OneToMany(mappedBy = "client")
@Filter(name="activeAccount", condition="active = :active")
private List<Account> accounts = new ArrayList<>( );
public enum AccountType {
DEBIT,
CREDIT
}
//Getters and setters omitted for brevity
//tag::mapping-filter-Client-example[]
@Entity(name = "Client")
public static class Client {
//end::mapping-filter-example[]
public Long getId() {
return id;
}
@Id
private Long id;
public void setId(Long id) {
this.id = id;
}
private String name;
public String getName() {
return name;
}
@OneToMany(
mappedBy = "client",
cascade = CascadeType.ALL
)
@Filter(
name="activeAccount",
condition="active_status = :active"
)
private List<Account> accounts = new ArrayList<>( );
public void setName(String name) {
this.name = name;
}
//Getters and setters omitted for brevity
//end::mapping-filter-Client-example[]
public Long getId() {
return id;
}
public List<Account> getAccounts() {
return accounts;
}
//tag::mapping-filter-example[]
}
public Client setId(Long id) {
this.id = id;
return this;
}
@Entity(name = "Account")
@FilterDef(name="activeAccount", parameters=@ParamDef( name="active", type="boolean" ) )
@Filter(name="activeAccount", condition="active = :active")
public static class Account {
public String getName() {
return name;
}
@Id
private Long id;
public Client setName(String name) {
this.name = name;
return this;
}
@ManyToOne
private Client client;
public List<Account> getAccounts() {
return accounts;
}
//tag::mapping-filter-Client-example[]
@Column(name = "account_type")
@Enumerated(EnumType.STRING)
private AccountType type;
public void addAccount(Account account) {
account.setClient( this );
this.accounts.add( account );
}
}
//end::mapping-filter-Client-example[]
private Double amount;
//tag::mapping-filter-Account-example[]
@Entity(name = "Account")
@FilterDef(
name="activeAccount",
parameters = @ParamDef(
name="active",
type="boolean"
)
)
@Filter(
name="activeAccount",
condition="active_status = :active"
)
public static class Account {
private Double rate;
@Id
private Long id;
private boolean active;
@ManyToOne(fetch = FetchType.LAZY)
private Client client;
//Getters and setters omitted for brevity
@Column(name = "account_type")
@Enumerated(EnumType.STRING)
private AccountType type;
//end::mapping-filter-example[]
public Long getId() {
return id;
}
private Double amount;
public void setId(Long id) {
this.id = id;
}
private Double rate;
public Client getClient() {
return client;
}
@Column(name = "active_status")
private boolean active;
public void setClient(Client client) {
this.client = client;
}
//Getters and setters omitted for brevity
//end::mapping-filter-Account-example[]
public Long getId() {
return id;
}
public AccountType getType() {
return type;
}
public Account setId(Long id) {
this.id = id;
return this;
}
public void setType(AccountType type) {
this.type = type;
}
public Client getClient() {
return client;
}
public Double getAmount() {
return amount;
}
public Account setClient(Client client) {
this.client = client;
return this;
}
public void setAmount(Double amount) {
this.amount = amount;
}
public AccountType getType() {
return type;
}
public Double getRate() {
return rate;
}
public Account setType(AccountType type) {
this.type = type;
return this;
}
public void setRate(Double rate) {
this.rate = rate;
}
public Double getAmount() {
return amount;
}
public boolean isActive() {
return active;
}
public Account setAmount(Double amount) {
this.amount = amount;
return this;
}
public void setActive(boolean active) {
this.active = active;
}
public Double getRate() {
return rate;
}
//tag::mapping-filter-example[]
}
//end::mapping-filter-example[]
public Account setRate(Double rate) {
this.rate = rate;
return this;
}
public boolean isActive() {
return active;
}
public Account setActive(boolean active) {
this.active = active;
return this;
}
//tag::mapping-filter-Account-example[]
}
//end::mapping-filter-Account-example[]
}