Skip to content

Commit 7362a49

Browse files
committed
HHH-11186 - Add examples for all Hibernate annotations
Document @polymorphism annotation
1 parent 5d49468 commit 7362a49

File tree

4 files changed

+241
-2
lines changed

4 files changed

+241
-2
lines changed

documentation/src/main/asciidoc/userguide/appendices/Annotations.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1158,7 +1158,7 @@ There are two possible `PolymorphismType` options:
11581158
EXPLICIT:: The current annotated entity is retrieved only if explicitly asked.
11591159
IMPLICIT:: The current annotated entity is retrieved if any of its super entity are retrieved. This is the default option.
11601160

1161-
//TODO: Add example
1161+
See the <<chapters/domain/inheritance.adoc#entity-inheritance-polymorphism, `@Polymorphism`>> section for more info.
11621162

11631163
[[annotations-hibernate-proxy]]
11641164
==== `@Proxy`

documentation/src/main/asciidoc/userguide/chapters/domain/inheritance.adoc

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,4 +310,67 @@ include::{extrasdir}/entity-inheritance-table-per-class-query-example.sql[]
310310
[IMPORTANT]
311311
====
312312
Polymorphic queries require multiple UNION queries, so be aware of the performance implications of a large class hierarchy.
313-
====
313+
====
314+
315+
[[entity-inheritance-polymorphism]]
316+
==== Implicit and explicit polymorphism
317+
318+
By default, when you query a base class entity,
319+
the polymorphic query will fetch all subclasses belonging to the base type.
320+
321+
However, you can even query
322+
*interfaces or base classes that don't belong to the JPA entity inheritance model*.
323+
324+
For instance, considering the following `DomainModelEntity` interface:
325+
326+
[[entity-inheritance-polymorphism-interface-example]]
327+
.Domain Model Entity interface
328+
====
329+
[source,java]
330+
----
331+
include::{sourcedir}/polymorphism/DomainModelEntity.java[tags=entity-inheritance-polymorphism-interface-example,indent=0]
332+
----
333+
====
334+
335+
If we have two entity mappings, a `Book` and a `Blog`,
336+
and the `Book` entity is mapped with the
337+
https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Polymorphism.html[`@Polymorphism`] annotation
338+
and taking the `PolymorphismType.EXPLICIT` setting:
339+
340+
[[entity-inheritance-polymorphism-mapping-example]]
341+
.`@Polymorphism` entity mapping
342+
====
343+
[source,java]
344+
----
345+
include::{sourcedir}/polymorphism/ExplicitPolymorphismTest.java[tags=entity-inheritance-polymorphism-mapping-example,indent=0]
346+
----
347+
====
348+
349+
If we have the following entity objects in our system:
350+
351+
[[entity-inheritance-polymorphism-persist-example]]
352+
.Domain Model entity objects
353+
====
354+
[source,java]
355+
----
356+
include::{sourcedir}/polymorphism/ExplicitPolymorphismTest.java[tags=entity-inheritance-polymorphism-persist-example,indent=0]
357+
----
358+
====
359+
360+
We can now query against the `DomainModelEntity` interface,
361+
and Hibernate is going to fetch only the entities that are either mapped with
362+
`@Polymorphism(type = PolymorphismType.IMPLICIT)`
363+
or they are not annotated at all with the `@Polymorphism` annotation (implying the IMPLICIT behavior):
364+
365+
[[entity-inheritance-polymorphism-fetch-example]]
366+
.Fetching Domain Model entities using non-mapped base class polymorphism
367+
====
368+
[source,java]
369+
----
370+
include::{sourcedir}/polymorphism/ExplicitPolymorphismTest.java[tags=entity-inheritance-polymorphism-fetch-example,indent=0]
371+
----
372+
====
373+
374+
Therefore, only the `Book` was fetched since the `Blog` entity was marked with the
375+
`@Polymorphism(type = PolymorphismType.EXPLICIT)` annotation, which instructs Hibernate
376+
to skip it when executing a polymorphic query against a non-mapped base class.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.userguide.inheritance.polymorphism;
8+
9+
/**
10+
* @author Vlad Mihalcea
11+
*/
12+
//tag::entity-inheritance-polymorphism-interface-example[]
13+
public interface DomainModelEntity<ID> {
14+
15+
ID getId();
16+
17+
Integer getVersion();
18+
}
19+
//end::entity-inheritance-polymorphism-interface-example[]
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.userguide.inheritance.polymorphism;
8+
9+
import java.util.List;
10+
import javax.persistence.Entity;
11+
import javax.persistence.Id;
12+
import javax.persistence.Version;
13+
14+
import org.hibernate.annotations.Polymorphism;
15+
import org.hibernate.annotations.PolymorphismType;
16+
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
17+
18+
import org.junit.Test;
19+
20+
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
21+
import static org.junit.Assert.assertEquals;
22+
import static org.junit.Assert.assertTrue;
23+
24+
/**
25+
* @author Vlad Mihalcea
26+
*/
27+
public class ExplicitPolymorphismTest extends BaseEntityManagerFunctionalTestCase {
28+
29+
@Override
30+
protected Class<?>[] getAnnotatedClasses() {
31+
return new Class<?>[] {
32+
Book.class,
33+
Blog.class,
34+
};
35+
}
36+
37+
@Test
38+
public void test() {
39+
doInJPA( this::entityManagerFactory, entityManager -> {
40+
//tag::entity-inheritance-polymorphism-persist-example[]
41+
Book book = new Book();
42+
book.setId( 1L );
43+
book.setAuthor( "Vlad Mihalcea" );
44+
book.setTitle( "High-Performance Java Persistence" );
45+
entityManager.persist( book );
46+
47+
Blog blog = new Blog();
48+
blog.setId( 1L );
49+
blog.setSite( "vladmihalcea.com" );
50+
entityManager.persist( blog );
51+
//end::entity-inheritance-polymorphism-persist-example[]
52+
} );
53+
54+
doInJPA( this::entityManagerFactory, entityManager -> {
55+
//tag::entity-inheritance-polymorphism-fetch-example[]
56+
List<DomainModelEntity> accounts = entityManager
57+
.createQuery(
58+
"select e " +
59+
"from org.hibernate.userguide.inheritance.polymorphism.DomainModelEntity e" )
60+
.getResultList();
61+
62+
assertEquals(1, accounts.size());
63+
assertTrue( accounts.get( 0 ) instanceof Book );
64+
//end::entity-inheritance-polymorphism-fetch-example[]
65+
} );
66+
}
67+
68+
69+
//tag::entity-inheritance-polymorphism-mapping-example[]
70+
@Entity(name = "Event")
71+
public static class Book implements DomainModelEntity<Long> {
72+
73+
@Id
74+
private Long id;
75+
76+
@Version
77+
private Integer version;
78+
79+
private String title;
80+
81+
private String author;
82+
83+
//Getter and setters omitted for brevity
84+
//end::entity-inheritance-polymorphism-mapping-example[]
85+
86+
@Override
87+
public Long getId() {
88+
return id;
89+
}
90+
91+
public void setId(Long id) {
92+
this.id = id;
93+
}
94+
95+
@Override
96+
public Integer getVersion() {
97+
return version;
98+
}
99+
100+
public String getTitle() {
101+
return title;
102+
}
103+
104+
public void setTitle(String title) {
105+
this.title = title;
106+
}
107+
108+
public String getAuthor() {
109+
return author;
110+
}
111+
112+
public void setAuthor(String author) {
113+
this.author = author;
114+
}
115+
//tag::entity-inheritance-polymorphism-mapping-example[]
116+
}
117+
118+
@Entity(name = "Blog")
119+
@Polymorphism(type = PolymorphismType.EXPLICIT)
120+
public static class Blog implements DomainModelEntity<Long> {
121+
122+
@Id
123+
private Long id;
124+
125+
@Version
126+
private Integer version;
127+
128+
private String site;
129+
130+
//Getter and setters omitted for brevity
131+
//end::entity-inheritance-polymorphism-mapping-example[]
132+
133+
@Override
134+
public Long getId() {
135+
return id;
136+
}
137+
138+
public void setId(Long id) {
139+
this.id = id;
140+
}
141+
142+
@Override
143+
public Integer getVersion() {
144+
return version;
145+
}
146+
147+
public String getSite() {
148+
return site;
149+
}
150+
151+
public void setSite(String site) {
152+
this.site = site;
153+
}
154+
//tag::entity-inheritance-polymorphism-mapping-example[]
155+
}
156+
//end::entity-inheritance-polymorphism-mapping-example[]
157+
}

0 commit comments

Comments
 (0)