HHH-11186 - Add examples for all Hibernate annotations

Document @Polymorphism annotation
This commit is contained in:
Vlad Mihalcea 2017-06-20 17:26:06 +03:00
parent 5d49468acf
commit 7362a49477
4 changed files with 241 additions and 2 deletions

View File

@ -1158,7 +1158,7 @@ There are two possible `PolymorphismType` options:
EXPLICIT:: The current annotated entity is retrieved only if explicitly asked. EXPLICIT:: The current annotated entity is retrieved only if explicitly asked.
IMPLICIT:: The current annotated entity is retrieved if any of its super entity are retrieved. This is the default option. IMPLICIT:: The current annotated entity is retrieved if any of its super entity are retrieved. This is the default option.
//TODO: Add example See the <<chapters/domain/inheritance.adoc#entity-inheritance-polymorphism, `@Polymorphism`>> section for more info.
[[annotations-hibernate-proxy]] [[annotations-hibernate-proxy]]
==== `@Proxy` ==== `@Proxy`

View File

@ -311,3 +311,66 @@ include::{extrasdir}/entity-inheritance-table-per-class-query-example.sql[]
==== ====
Polymorphic queries require multiple UNION queries, so be aware of the performance implications of a large class hierarchy. Polymorphic queries require multiple UNION queries, so be aware of the performance implications of a large class hierarchy.
==== ====
[[entity-inheritance-polymorphism]]
==== Implicit and explicit polymorphism
By default, when you query a base class entity,
the polymorphic query will fetch all subclasses belonging to the base type.
However, you can even query
*interfaces or base classes that don't belong to the JPA entity inheritance model*.
For instance, considering the following `DomainModelEntity` interface:
[[entity-inheritance-polymorphism-interface-example]]
.Domain Model Entity interface
====
[source,java]
----
include::{sourcedir}/polymorphism/DomainModelEntity.java[tags=entity-inheritance-polymorphism-interface-example,indent=0]
----
====
If we have two entity mappings, a `Book` and a `Blog`,
and the `Book` entity is mapped with the
https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Polymorphism.html[`@Polymorphism`] annotation
and taking the `PolymorphismType.EXPLICIT` setting:
[[entity-inheritance-polymorphism-mapping-example]]
.`@Polymorphism` entity mapping
====
[source,java]
----
include::{sourcedir}/polymorphism/ExplicitPolymorphismTest.java[tags=entity-inheritance-polymorphism-mapping-example,indent=0]
----
====
If we have the following entity objects in our system:
[[entity-inheritance-polymorphism-persist-example]]
.Domain Model entity objects
====
[source,java]
----
include::{sourcedir}/polymorphism/ExplicitPolymorphismTest.java[tags=entity-inheritance-polymorphism-persist-example,indent=0]
----
====
We can now query against the `DomainModelEntity` interface,
and Hibernate is going to fetch only the entities that are either mapped with
`@Polymorphism(type = PolymorphismType.IMPLICIT)`
or they are not annotated at all with the `@Polymorphism` annotation (implying the IMPLICIT behavior):
[[entity-inheritance-polymorphism-fetch-example]]
.Fetching Domain Model entities using non-mapped base class polymorphism
====
[source,java]
----
include::{sourcedir}/polymorphism/ExplicitPolymorphismTest.java[tags=entity-inheritance-polymorphism-fetch-example,indent=0]
----
====
Therefore, only the `Book` was fetched since the `Blog` entity was marked with the
`@Polymorphism(type = PolymorphismType.EXPLICIT)` annotation, which instructs Hibernate
to skip it when executing a polymorphic query against a non-mapped base class.

View File

@ -0,0 +1,19 @@
/*
* 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.inheritance.polymorphism;
/**
* @author Vlad Mihalcea
*/
//tag::entity-inheritance-polymorphism-interface-example[]
public interface DomainModelEntity<ID> {
ID getId();
Integer getVersion();
}
//end::entity-inheritance-polymorphism-interface-example[]

View File

@ -0,0 +1,157 @@
/*
* 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.inheritance.polymorphism;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Version;
import org.hibernate.annotations.Polymorphism;
import org.hibernate.annotations.PolymorphismType;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* @author Vlad Mihalcea
*/
public class ExplicitPolymorphismTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Book.class,
Blog.class,
};
}
@Test
public void test() {
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::entity-inheritance-polymorphism-persist-example[]
Book book = new Book();
book.setId( 1L );
book.setAuthor( "Vlad Mihalcea" );
book.setTitle( "High-Performance Java Persistence" );
entityManager.persist( book );
Blog blog = new Blog();
blog.setId( 1L );
blog.setSite( "vladmihalcea.com" );
entityManager.persist( blog );
//end::entity-inheritance-polymorphism-persist-example[]
} );
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::entity-inheritance-polymorphism-fetch-example[]
List<DomainModelEntity> accounts = entityManager
.createQuery(
"select e " +
"from org.hibernate.userguide.inheritance.polymorphism.DomainModelEntity e" )
.getResultList();
assertEquals(1, accounts.size());
assertTrue( accounts.get( 0 ) instanceof Book );
//end::entity-inheritance-polymorphism-fetch-example[]
} );
}
//tag::entity-inheritance-polymorphism-mapping-example[]
@Entity(name = "Event")
public static class Book implements DomainModelEntity<Long> {
@Id
private Long id;
@Version
private Integer version;
private String title;
private String author;
//Getter and setters omitted for brevity
//end::entity-inheritance-polymorphism-mapping-example[]
@Override
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Override
public Integer getVersion() {
return version;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
//tag::entity-inheritance-polymorphism-mapping-example[]
}
@Entity(name = "Blog")
@Polymorphism(type = PolymorphismType.EXPLICIT)
public static class Blog implements DomainModelEntity<Long> {
@Id
private Long id;
@Version
private Integer version;
private String site;
//Getter and setters omitted for brevity
//end::entity-inheritance-polymorphism-mapping-example[]
@Override
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Override
public Integer getVersion() {
return version;
}
public String getSite() {
return site;
}
public void setSite(String site) {
this.site = site;
}
//tag::entity-inheritance-polymorphism-mapping-example[]
}
//end::entity-inheritance-polymorphism-mapping-example[]
}