HHH-7010 - Document mapping annotations
List and describe all JPA and Hibernate.annotations
This commit is contained in:
parent
0439e855cc
commit
2ecfd488b7
|
@ -31,6 +31,7 @@ include::chapters/envers/Envers.adoc[]
|
||||||
include::chapters/portability/Portability.adoc[]
|
include::chapters/portability/Portability.adoc[]
|
||||||
|
|
||||||
include::appendices/Configurations.adoc[]
|
include::appendices/Configurations.adoc[]
|
||||||
|
include::appendices/Annotations.adoc[]
|
||||||
include::appendices/BestPractices.adoc[]
|
include::appendices/BestPractices.adoc[]
|
||||||
include::appendices/Legacy_Bootstrap.adoc[]
|
include::appendices/Legacy_Bootstrap.adoc[]
|
||||||
include::appendices/Legacy_DomainModel.adoc[]
|
include::appendices/Legacy_DomainModel.adoc[]
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -207,7 +207,7 @@ However, `LAZY` associations must be initialized prior to being accessed. Otherw
|
||||||
There are good and bad ways to treat the `LazyInitializationException`.
|
There are good and bad ways to treat the `LazyInitializationException`.
|
||||||
|
|
||||||
https://vladmihalcea.com/2016/09/13/the-best-way-to-handle-the-lazyinitializationexception/[The best way to deal with `LazyInitializationException`] is to fetch all the required associations prior to closing the Persistence Context.
|
https://vladmihalcea.com/2016/09/13/the-best-way-to-handle-the-lazyinitializationexception/[The best way to deal with `LazyInitializationException`] is to fetch all the required associations prior to closing the Persistence Context.
|
||||||
The `JOIN FETCH` directive is goof for `@ManyToOne` and `OneToOne` associations, and for at most one collection (e.g. `@OneToMany` or `@ManyToMany`).
|
The `JOIN FETCH` directive is good for `@ManyToOne` and `OneToOne` associations, and for at most one collection (e.g. `@OneToMany` or `@ManyToMany`).
|
||||||
If you need to fetch multiple collections, to avoid a Cartesian Product, you should use secondary queries which are triggered either by navigating the `LAZY` association or by calling `Hibernate#initialize(proxy)` method.
|
If you need to fetch multiple collections, to avoid a Cartesian Product, you should use secondary queries which are triggered either by navigating the `LAZY` association or by calling `Hibernate#initialize(proxy)` method.
|
||||||
|
|
||||||
[[best-practices-caching]]
|
[[best-practices-caching]]
|
||||||
|
|
|
@ -409,7 +409,7 @@ include::{extrasdir}/basic/basic-custom-type-BitSetUserType-persistence-sql-exam
|
||||||
Hibernate supports the mapping of Java enums as basic value types in a number of different ways.
|
Hibernate supports the mapping of Java enums as basic value types in a number of different ways.
|
||||||
|
|
||||||
[[basic-enums-Enumerated]]
|
[[basic-enums-Enumerated]]
|
||||||
===== @Enumerated
|
===== `@Enumerated`
|
||||||
|
|
||||||
The original JPA-compliant way to map enums was via the `@Enumerated` and `@MapKeyEnumerated` for map keys annotations which works on the principle that the enum values are stored according to one of 2 strategies indicated by `javax.persistence.EnumType`:
|
The original JPA-compliant way to map enums was via the `@Enumerated` and `@MapKeyEnumerated` for map keys annotations which works on the principle that the enum values are stored according to one of 2 strategies indicated by `javax.persistence.EnumType`:
|
||||||
|
|
||||||
|
@ -1083,7 +1083,7 @@ include::{sourcedir}/basic/JpaQuotingTest.java[tags=basic-jpa-quoting-example]
|
||||||
|
|
||||||
Because `name` and `number` are reserved words, the `Product` entity mapping uses backtricks to quote these column names.
|
Because `name` and `number` are reserved words, the `Product` entity mapping uses backtricks to quote these column names.
|
||||||
|
|
||||||
When saving teh following `Product entity`, Hibernate generates the following SQL insert statement:
|
When saving the following `Product entity`, Hibernate generates the following SQL insert statement:
|
||||||
|
|
||||||
[[basic-quoting-persistence-example]]
|
[[basic-quoting-persistence-example]]
|
||||||
.Persisting a quoted column name
|
.Persisting a quoted column name
|
||||||
|
@ -1442,7 +1442,7 @@ include::{extrasdir}/basic/mapping-filter-collection-query-example.sql[]
|
||||||
|
|
||||||
[NOTE]
|
[NOTE]
|
||||||
====
|
====
|
||||||
The main advantage of `@Filter` over teh `@Where` clause is that the filtering criteria can be customized at runtime.
|
The main advantage of `@Filter` over the `@Where` clause is that the filtering criteria can be customized at runtime.
|
||||||
====
|
====
|
||||||
|
|
||||||
[WARNING]
|
[WARNING]
|
||||||
|
|
|
@ -2,7 +2,7 @@ SELECT
|
||||||
phones0_.Person_id AS Person_i1_1_0_,
|
phones0_.Person_id AS Person_i1_1_0_,
|
||||||
phones0_.phones_id AS phones_i2_1_0_,
|
phones0_.phones_id AS phones_i2_1_0_,
|
||||||
unidirecti1_.id AS id1_2_1_,
|
unidirecti1_.id AS id1_2_1_,
|
||||||
unidirecti1_.number AS number2_2_1_,
|
unidirecti1_."number" AS number2_2_1_,
|
||||||
unidirecti1_.type AS type3_2_1_
|
unidirecti1_.type AS type3_2_1_
|
||||||
FROM
|
FROM
|
||||||
Person_Phone phones0_
|
Person_Phone phones0_
|
||||||
|
@ -11,4 +11,4 @@ INNER JOIN
|
||||||
WHERE
|
WHERE
|
||||||
phones0_.Person_id = 1
|
phones0_.Person_id = 1
|
||||||
ORDER BY
|
ORDER BY
|
||||||
unidirecti1_.number
|
unidirecti1_."number"
|
|
@ -43,6 +43,9 @@ According to JPA only the following types should be used as identifier attribute
|
||||||
|
|
||||||
Any types used for identifier attributes beyond this list will not be portable.
|
Any types used for identifier attributes beyond this list will not be portable.
|
||||||
|
|
||||||
|
[[identifiers-simple-assigned]]
|
||||||
|
===== Assigned identifiers
|
||||||
|
|
||||||
Values for simple identifiers can be assigned, as we have seen in the examples above.
|
Values for simple identifiers can be assigned, as we have seen in the examples above.
|
||||||
The expectation for assigned identifier values is that the application assigns (sets them on the entity attribute) prior to calling save/persist.
|
The expectation for assigned identifier values is that the application assigns (sets them on the entity attribute) prior to calling save/persist.
|
||||||
|
|
||||||
|
@ -54,6 +57,9 @@ include::{sourcedir}/id/SimpleAssigned.java[]
|
||||||
----
|
----
|
||||||
====
|
====
|
||||||
|
|
||||||
|
[[identifiers-simple-generated]]
|
||||||
|
===== Generated identifiers
|
||||||
|
|
||||||
Values for simple identifiers can be generated. To denote that an identifier attribute is generated, it is annotated with `javax.persistence.GeneratedValue`
|
Values for simple identifiers can be generated. To denote that an identifier attribute is generated, it is annotated with `javax.persistence.GeneratedValue`
|
||||||
|
|
||||||
.Simple generated identifier
|
.Simple generated identifier
|
||||||
|
@ -93,7 +99,7 @@ The attributes making up the composition can be either basic, composite, ManyToO
|
||||||
Note especially that collections and one-to-ones are never appropriate.
|
Note especially that collections and one-to-ones are never appropriate.
|
||||||
|
|
||||||
[[identifiers-composite-aggregated]]
|
[[identifiers-composite-aggregated]]
|
||||||
==== Composite identifiers - aggregated (EmbeddedId)
|
==== Composite identifiers with `@EmbeddedId`
|
||||||
|
|
||||||
Modeling a composite identifier using an EmbeddedId simply means defining an embeddable to be a composition for the one or more attributes making up the identifier,
|
Modeling a composite identifier using an EmbeddedId simply means defining an embeddable to be a composition for the one or more attributes making up the identifier,
|
||||||
and then exposing an attribute of that embeddable type on the entity.
|
and then exposing an attribute of that embeddable type on the entity.
|
||||||
|
@ -124,7 +130,7 @@ In JPA terms one would use "derived identifiers"; for details, see <<identifiers
|
||||||
====
|
====
|
||||||
|
|
||||||
[[identifiers-composite-nonaggregated]]
|
[[identifiers-composite-nonaggregated]]
|
||||||
==== Composite identifiers - non-aggregated (IdClass)
|
==== Composite identifiers with `@IdClass`
|
||||||
|
|
||||||
Modeling a composite identifier using an IdClass differs from using an EmbeddedId in that the entity defines each individual attribute making up the composition.
|
Modeling a composite identifier using an IdClass differs from using an EmbeddedId in that the entity defines each individual attribute making up the composition.
|
||||||
The IdClass simply acts as a "shadow".
|
The IdClass simply acts as a "shadow".
|
||||||
|
@ -165,7 +171,7 @@ Use of this feature may or may not be portable from a JPA perspective.
|
||||||
====
|
====
|
||||||
|
|
||||||
[[identifiers-composite-associations]]
|
[[identifiers-composite-associations]]
|
||||||
==== Composite identifiers - associations
|
==== Composite identifiers with associations
|
||||||
|
|
||||||
Hibernate allows defining a composite identifier out of entity associations.
|
Hibernate allows defining a composite identifier out of entity associations.
|
||||||
In the following example, the `PersonAddress` entity identifier is formed of two `@ManyToOne` associations.
|
In the following example, the `PersonAddress` entity identifier is formed of two `@ManyToOne` associations.
|
||||||
|
@ -401,6 +407,7 @@ Applications can also implement and use their own optimizer strategies, as defin
|
||||||
|
|
||||||
JPA 2.0 added support for derived identifiers which allow an entity to borrow the identifier from a many-to-one or one-to-one association.
|
JPA 2.0 added support for derived identifiers which allow an entity to borrow the identifier from a many-to-one or one-to-one association.
|
||||||
|
|
||||||
|
[[identifiers-derived-mapsid]]
|
||||||
.Derived identifier with `@MapsId`
|
.Derived identifier with `@MapsId`
|
||||||
====
|
====
|
||||||
[source,java]
|
[source,java]
|
||||||
|
@ -415,6 +422,7 @@ The `@MapsId` annotation can also reference columns from an `@EmbeddedId` identi
|
||||||
|
|
||||||
The previous example can also be mapped using `@PrimaryKeyJoinColumn`.
|
The previous example can also be mapped using `@PrimaryKeyJoinColumn`.
|
||||||
|
|
||||||
|
[[identifiers-derived-primarykeyjoincolumn]]
|
||||||
.Derived identifier `@PrimaryKeyJoinColumn`
|
.Derived identifier `@PrimaryKeyJoinColumn`
|
||||||
====
|
====
|
||||||
[source,java]
|
[source,java]
|
||||||
|
|
|
@ -122,6 +122,7 @@ include::{sourcedir}/natural_id/MutableNaturalIdSynchronization.java[]
|
||||||
|
|
||||||
Not only can this NaturalId-to-PK resolution be cached in the Session, but we can also have it cached in the second-level cache if second level caching is enabled.
|
Not only can this NaturalId-to-PK resolution be cached in the Session, but we can also have it cached in the second-level cache if second level caching is enabled.
|
||||||
|
|
||||||
|
[[naturalid-caching]]
|
||||||
.Natural id caching
|
.Natural id caching
|
||||||
====
|
====
|
||||||
[source,java]
|
[source,java]
|
||||||
|
|
|
@ -151,7 +151,7 @@ For callback methods defined on an entity listener class, the method must have a
|
||||||
A callback method can throw a `RuntimeException`.
|
A callback method can throw a `RuntimeException`.
|
||||||
If the callback method does throw a `RuntimeException`, then the current transaction, if any, must be rolled back.
|
If the callback method does throw a `RuntimeException`, then the current transaction, if any, must be rolled back.
|
||||||
|
|
||||||
A callback method must not invoke EntityManager or Query methods!
|
A callback method must not invoke `EntityManager` or `Query` methods!
|
||||||
|
|
||||||
It is possible that multiple callback methods are defined for a particular lifecycle event.
|
It is possible that multiple callback methods are defined for a particular lifecycle event.
|
||||||
When that is the case, the defined order of execution is well defined by the JPA spec (specifically section 3.5.4):
|
When that is the case, the defined order of execution is well defined by the JPA spec (specifically section 3.5.4):
|
||||||
|
|
|
@ -13,7 +13,7 @@ import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
import javax.persistence.OrderBy;
|
import javax.persistence.OrderColumn;
|
||||||
|
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ public class UnidirectionalOrderColumnListTest extends BaseEntityManagerFunction
|
||||||
|
|
||||||
//tag::collections-unidirectional-ordered-list-order-column-example[]
|
//tag::collections-unidirectional-ordered-list-order-column-example[]
|
||||||
@OneToMany(cascade = CascadeType.ALL)
|
@OneToMany(cascade = CascadeType.ALL)
|
||||||
@OrderBy("number")
|
@OrderColumn(name = "order_id")
|
||||||
private List<Phone> phones = new ArrayList<>();
|
private List<Phone> phones = new ArrayList<>();
|
||||||
//end::collections-unidirectional-ordered-list-order-column-example[]
|
//end::collections-unidirectional-ordered-list-order-column-example[]
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
import javax.persistence.OrderColumn;
|
import javax.persistence.OrderBy;
|
||||||
|
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ public class UnidirectionalOrderedByListTest extends BaseEntityManagerFunctional
|
||||||
@Id
|
@Id
|
||||||
private Long id;
|
private Long id;
|
||||||
@OneToMany(cascade = CascadeType.ALL)
|
@OneToMany(cascade = CascadeType.ALL)
|
||||||
@OrderColumn(name = "order_id")
|
@OrderBy("number")
|
||||||
private List<Phone> phones = new ArrayList<>();
|
private List<Phone> phones = new ArrayList<>();
|
||||||
|
|
||||||
public Person() {
|
public Person() {
|
||||||
|
|
|
@ -83,7 +83,8 @@ public class EnumerationConverterTest extends BaseEntityManagerFunctionalTestCas
|
||||||
}
|
}
|
||||||
|
|
||||||
@Converter
|
@Converter
|
||||||
public static class GenderConverter implements AttributeConverter<Gender, Character> {
|
public static class GenderConverter
|
||||||
|
implements AttributeConverter<Gender, Character> {
|
||||||
|
|
||||||
public Character convertToDatabaseColumn( Gender value ) {
|
public Character convertToDatabaseColumn( Gender value ) {
|
||||||
if ( value == null ) {
|
if ( value == null ) {
|
||||||
|
|
Loading…
Reference in New Issue