HHH-7010 - Document mapping annotations

List and describe all JPA and Hibernate.annotations
This commit is contained in:
Vlad Mihalcea 2016-10-14 11:50:02 +03:00
parent 0439e855cc
commit 2ecfd488b7
11 changed files with 1253 additions and 15 deletions

View File

@ -31,6 +31,7 @@ include::chapters/envers/Envers.adoc[]
include::chapters/portability/Portability.adoc[]
include::appendices/Configurations.adoc[]
include::appendices/Annotations.adoc[]
include::appendices/BestPractices.adoc[]
include::appendices/Legacy_Bootstrap.adoc[]
include::appendices/Legacy_DomainModel.adoc[]

File diff suppressed because it is too large Load Diff

View File

@ -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`.
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.
[[best-practices-caching]]

View File

@ -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.
[[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`:
@ -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.
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]]
.Persisting a quoted column name
@ -1442,7 +1442,7 @@ include::{extrasdir}/basic/mapping-filter-collection-query-example.sql[]
[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]

View File

@ -2,7 +2,7 @@ SELECT
phones0_.Person_id AS Person_i1_1_0_,
phones0_.phones_id AS phones_i2_1_0_,
unidirecti1_.id AS id1_2_1_,
unidirecti1_.number AS number2_2_1_,
unidirecti1_."number" AS number2_2_1_,
unidirecti1_.type AS type3_2_1_
FROM
Person_Phone phones0_
@ -11,4 +11,4 @@ INNER JOIN
WHERE
phones0_.Person_id = 1
ORDER BY
unidirecti1_.number
unidirecti1_."number"

View File

@ -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.
[[identifiers-simple-assigned]]
===== Assigned identifiers
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.
@ -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`
.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.
[[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,
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]]
==== 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.
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]]
==== Composite identifiers - associations
==== Composite identifiers with 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.
@ -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.
[[identifiers-derived-mapsid]]
.Derived identifier with `@MapsId`
====
[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`.
[[identifiers-derived-primarykeyjoincolumn]]
.Derived identifier `@PrimaryKeyJoinColumn`
====
[source,java]

View File

@ -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.
[[naturalid-caching]]
.Natural id caching
====
[source,java]

View File

@ -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`.
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.
When that is the case, the defined order of execution is well defined by the JPA spec (specifically section 3.5.4):

View File

@ -13,7 +13,7 @@ import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.OrderColumn;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
@ -56,7 +56,7 @@ public class UnidirectionalOrderColumnListTest extends BaseEntityManagerFunction
//tag::collections-unidirectional-ordered-list-order-column-example[]
@OneToMany(cascade = CascadeType.ALL)
@OrderBy("number")
@OrderColumn(name = "order_id")
private List<Phone> phones = new ArrayList<>();
//end::collections-unidirectional-ordered-list-order-column-example[]

View File

@ -13,7 +13,7 @@ import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OrderColumn;
import javax.persistence.OrderBy;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
@ -55,7 +55,7 @@ public class UnidirectionalOrderedByListTest extends BaseEntityManagerFunctional
@Id
private Long id;
@OneToMany(cascade = CascadeType.ALL)
@OrderColumn(name = "order_id")
@OrderBy("number")
private List<Phone> phones = new ArrayList<>();
public Person() {

View File

@ -83,7 +83,8 @@ public class EnumerationConverterTest extends BaseEntityManagerFunctionalTestCas
}
@Converter
public static class GenderConverter implements AttributeConverter<Gender, Character> {
public static class GenderConverter
implements AttributeConverter<Gender, Character> {
public Character convertToDatabaseColumn( Gender value ) {
if ( value == null ) {