HHH-11186 - Add examples for all Hibernate annotations
Document @Polymorphism annotation
This commit is contained in:
parent
5d49468acf
commit
7362a49477
|
@ -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`
|
||||||
|
|
|
@ -310,4 +310,67 @@ include::{extrasdir}/entity-inheritance-table-per-class-query-example.sql[]
|
||||||
[IMPORTANT]
|
[IMPORTANT]
|
||||||
====
|
====
|
||||||
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.
|
|
@ -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[]
|
|
@ -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[]
|
||||||
|
}
|
Loading…
Reference in New Issue