HHH-11186 - Add examples for all Hibernate annotations
Document more annotations: - @FilterJoinTable
This commit is contained in:
parent
91ebadb209
commit
8f3d58601d
|
@ -789,11 +789,14 @@ See the <<chapters/domain/basic_types.adoc#mapping-filter-example,Filter mapping
|
|||
==== `@FilterDefs`
|
||||
|
||||
The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/FilterDefs.html[`@FilterDefs`] annotation is used to group multiple <<annotations-hibernate-filterdef>> annotations.
|
||||
|
||||
[[annotations-hibernate-filterjointable]]
|
||||
==== `@FilterJoinTable`
|
||||
|
||||
The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/FilterJoinTable.html[`@FilterJoinTable`] annotation is used to add `@Filter` capabilities to a join table collection.
|
||||
|
||||
See the <<chapters/domain/basic_types.adoc#mapping-column-filter-join-table,FilterJoinTable mapping>> section for more info.
|
||||
|
||||
[[annotations-hibernate-filterjointables]]
|
||||
==== `@FilterJoinTables`
|
||||
|
||||
|
|
|
@ -1514,7 +1514,7 @@ include::{extrasdir}/basic/mapping-filter-entity-query-example.sql[]
|
|||
----
|
||||
====
|
||||
|
||||
Jut like with entities, collections can be filtered as well, but only if the filter is explicilty enabled on the currently running Hibernate `Session`.
|
||||
Just like with entities, 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-filter-collection-query-example]]
|
||||
|
@ -1547,6 +1547,56 @@ Afterward, every other Session will get the filtered collection from the cache,
|
|||
For this reason, the second-level collection cache is limited to storing whole collections, and not subsets.
|
||||
====
|
||||
|
||||
[[mapping-column-filter-join-table]]
|
||||
==== @FilterJoinTable
|
||||
|
||||
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:
|
||||
|
||||
[[mapping-filter-join-table-example]]
|
||||
.`@FilterJoinTable` mapping usage
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{sourcedir}/basic/FilterJoinTableTest.java[tags=mapping-filter-join-table-example]
|
||||
----
|
||||
====
|
||||
|
||||
If the database contains the following entities:
|
||||
|
||||
[[mapping-filter-join-table-persistence-example]]
|
||||
.Persisting an fetching entities with a `@FilterJoinTable` mapping
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{sourcedir}/basic/FilterJoinTableTest.java[tags=mapping-filter-join-table-persistence-example]
|
||||
----
|
||||
|
||||
[source, SQL, indent=0]
|
||||
----
|
||||
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.
|
||||
|
||||
[[mapping-filter-collection-query-example]]
|
||||
.Traversing collections mapped with `@FilterJoinTable`
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{sourcedir}/basic/FilterJoinTableTest.java[tags=mapping-filter-join-table-collection-query-example]
|
||||
----
|
||||
|
||||
[source, SQL, indent=0]
|
||||
----
|
||||
include::{extrasdir}/basic/mapping-filter-join-table-collection-query-example.sql[]
|
||||
----
|
||||
====
|
||||
|
||||
[[mapping-column-any]]
|
||||
==== @Any mapping
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
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.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 = ?
|
||||
|
||||
-- binding parameter [1] as [INTEGER] - [1]
|
||||
-- binding parameter [2] as [BIGINT] - [1]
|
|
@ -0,0 +1,23 @@
|
|||
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 (active, 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)
|
||||
VALUES (true, 250.0, 1, 0.0105, 'DEBIT', 3)
|
||||
|
||||
INSERT INTO Client_Account (Client_id, order_id, accounts_id)
|
||||
VALUES (1, 0, 1)
|
||||
|
||||
INSERT INTO Client_Account (Client_id, order_id, accounts_id)
|
||||
VALUES (1, 0, 1)
|
||||
|
||||
INSERT INTO Client_Account (Client_id, order_id, accounts_id)
|
||||
VALUES (1, 1, 2)
|
||||
|
||||
INSERT INTO Client_Account (Client_id, order_id, accounts_id)
|
||||
VALUES (1, 2, 3)
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.userguide.mapping.basic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OrderColumn;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.annotations.Filter;
|
||||
import org.hibernate.annotations.FilterDef;
|
||||
import org.hibernate.annotations.FilterJoinTable;
|
||||
import org.hibernate.annotations.ParamDef;
|
||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
public class FilterJoinTableTest extends BaseEntityManagerFunctionalTestCase {
|
||||
|
||||
private static final Logger log = Logger.getLogger( FilterJoinTableTest.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 -> {
|
||||
|
||||
Client client = new Client();
|
||||
client.setId( 1L );
|
||||
client.setName( "John Doe" );
|
||||
entityManager.persist( client );
|
||||
|
||||
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 );
|
||||
|
||||
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 );
|
||||
|
||||
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[]
|
||||
|
||||
//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 -> {
|
||||
log.infof( "Activate filter [%s]", "firstAccounts");
|
||||
|
||||
Client client = entityManager.find( Client.class, 1L );
|
||||
|
||||
entityManager
|
||||
.unwrap( Session.class )
|
||||
.enableFilter( "firstAccounts" )
|
||||
.setParameter( "maxOrderId", 1);
|
||||
|
||||
assertEquals( 2, client.getAccounts().size());
|
||||
} );
|
||||
//end::mapping-filter-join-table-collection-query-example[]
|
||||
}
|
||||
|
||||
//tag::mapping-filter-join-table-example[]
|
||||
public enum AccountType {
|
||||
DEBIT,
|
||||
CREDIT
|
||||
}
|
||||
|
||||
@Entity(name = "Client")
|
||||
@FilterDef(name="firstAccounts", parameters=@ParamDef( name="maxOrderId", type="int" ) )
|
||||
@Filter(name="firstAccounts", condition="order_id <= :maxOrderId")
|
||||
public static class Client {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
@OneToMany
|
||||
@OrderColumn(name = "order_id")
|
||||
@FilterJoinTable(name="firstAccounts", condition="order_id <= :maxOrderId")
|
||||
private List<Account> accounts = new ArrayList<>( );
|
||||
|
||||
//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 String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<Account> getAccounts() {
|
||||
return accounts;
|
||||
}
|
||||
//tag::mapping-filter-join-table-example[]
|
||||
}
|
||||
|
||||
@Entity(name = "Account")
|
||||
public static class Account {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@Column(name = "account_type")
|
||||
@Enumerated(EnumType.STRING)
|
||||
private AccountType type;
|
||||
|
||||
private Double amount;
|
||||
|
||||
private Double rate;
|
||||
|
||||
private boolean active;
|
||||
|
||||
//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 AccountType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(AccountType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Double getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(Double amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public Double getRate() {
|
||||
return rate;
|
||||
}
|
||||
|
||||
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[]
|
||||
}
|
Loading…
Reference in New Issue