HHH-11186 - Add examples for all Hibernate annotations
Document more annotations: - @Generated
This commit is contained in:
parent
ac22294bb3
commit
6a69f10f46
|
@ -68,6 +68,7 @@ dependencies {
|
|||
testRuntime( libraries.postgresql )
|
||||
testRuntime( libraries.mysql )
|
||||
testRuntime( libraries.mariadb )
|
||||
testRuntime( libraries.mssql )
|
||||
|
||||
if (db.equalsIgnoreCase("oracle")) {
|
||||
dependencies {
|
||||
|
@ -75,12 +76,6 @@ dependencies {
|
|||
}
|
||||
}
|
||||
|
||||
if (db.equalsIgnoreCase("mssql")) {
|
||||
dependencies {
|
||||
testRuntime( libraries.mssql )
|
||||
}
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Java 9 ftw!
|
||||
if ( JavaVersion.current().isJava9Compatible() ) {
|
||||
|
|
|
@ -823,6 +823,8 @@ See the <<chapters/domain/basic_types.adoc#mapping-column-formula-example,`@Form
|
|||
|
||||
The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Generated.html[`@Generated`] annotation is used to specify that the current annotated entity attribute is generated by the database.
|
||||
|
||||
See the <<chapters/domain/basic_types.adoc#mapping-generated-Generated,`@Generated` mapping>> section for more info.
|
||||
|
||||
[[annotations-hibernate-generatortype]]
|
||||
==== `@GeneratorType`
|
||||
|
||||
|
|
|
@ -1201,12 +1201,63 @@ When Hibernate issues an SQL INSERT or UPDATE for an entity that has defined gen
|
|||
Properties marked as generated must additionally be _non-insertable_ and _non-updateable_.
|
||||
Only `@Version` and `@Basic` types can be marked as generated.
|
||||
|
||||
`never` (the default):: the given property value is not generated within the database.
|
||||
`insert`:: the given property value is generated on insert, but is not regenerated on subsequent updates. Properties like _creationTimestamp_ fall into this category.
|
||||
`always`:: the property value is generated both on insert and on update.
|
||||
`NEVER` (the default):: the given property value is not generated within the database.
|
||||
`INSERT`:: the given property value is generated on insert, but is not regenerated on subsequent updates. Properties like _creationTimestamp_ fall into this category.
|
||||
`ALWAYS`:: the property value is generated both on insert and on update.
|
||||
|
||||
To mark a property as generated, use The Hibernate specific `@Generated` annotation.
|
||||
|
||||
[[mapping-generated-Generated]]
|
||||
===== `@Generated` annotation
|
||||
|
||||
The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Generated.html[`@Generated`] annotation is used so that Hibernate can fetch the currently annotated property after the entity has been persisted or updated.
|
||||
For this reason, the `@Generated` annotation accepts a https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/GenerationTime.html[`GenerationTime`] enum value.
|
||||
|
||||
Considering the following entity:
|
||||
|
||||
[[mapping-generated-Generated-example]]
|
||||
.`@Generated` mapping example
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{sourcedir}/generated/GeneratedTest.java[tags=mapping-generated-Generated-example]
|
||||
----
|
||||
====
|
||||
|
||||
When the `Person` entity is persisted, Hibernate is going to fetch the calculated `fullName` column from the database,
|
||||
which concatenates the first, middle, and last name.
|
||||
|
||||
[[mapping-generated-Generated-persist-example]]
|
||||
.`@Generated` persist example
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{sourcedir}/generated/GeneratedTest.java[tags=mapping-generated-Generated-persist-example]
|
||||
----
|
||||
|
||||
[source, SQL, indent=0]
|
||||
----
|
||||
include::{extrasdir}/basic/mapping-generated-Generated-persist-example.sql[]
|
||||
----
|
||||
====
|
||||
|
||||
The same goes when the `Person` entity is updated.
|
||||
Hibernate is going to fetch the calculated `fullName` column from the database after the entity is modified.
|
||||
|
||||
[[mapping-generated-Generated-update-example]]
|
||||
.`@Generated` update example
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{sourcedir}/generated/GeneratedTest.java[tags=mapping-generated-Generated-update-example]
|
||||
----
|
||||
|
||||
[source, SQL, indent=0]
|
||||
----
|
||||
include::{extrasdir}/basic/mapping-generated-Generated-update-example.sql[]
|
||||
----
|
||||
====
|
||||
|
||||
[[mapping-generated-CreationTimestamp]]
|
||||
===== `@CreationTimestamp` annotation
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
INSERT INTO Person
|
||||
(
|
||||
firstName,
|
||||
lastName,
|
||||
middleName1,
|
||||
middleName2,
|
||||
middleName3,
|
||||
middleName4,
|
||||
middleName5,
|
||||
id
|
||||
)
|
||||
values
|
||||
(?, ?, ?, ?, ?, ?, ?, ?)
|
||||
|
||||
-- binding parameter [1] as [VARCHAR] - [John]
|
||||
-- binding parameter [2] as [VARCHAR] - [Doe]
|
||||
-- binding parameter [3] as [VARCHAR] - [Flávio]
|
||||
-- binding parameter [4] as [VARCHAR] - [André]
|
||||
-- binding parameter [5] as [VARCHAR] - [Frederico]
|
||||
-- binding parameter [6] as [VARCHAR] - [Rúben]
|
||||
-- binding parameter [7] as [VARCHAR] - [Artur]
|
||||
-- binding parameter [8] as [BIGINT] - [1]
|
||||
|
||||
SELECT
|
||||
p.fullName as fullName3_0_
|
||||
FROM
|
||||
Person p
|
||||
WHERE
|
||||
p.id=?
|
||||
|
||||
-- binding parameter [1] as [BIGINT] - [1]
|
||||
-- extracted value ([fullName3_0_] : [VARCHAR]) - [John Flávio André Frederico Rúben Artur Doe]
|
|
@ -0,0 +1,31 @@
|
|||
UPDATE
|
||||
Person
|
||||
SET
|
||||
firstName=?,
|
||||
lastName=?,
|
||||
middleName1=?,
|
||||
middleName2=?,
|
||||
middleName3=?,
|
||||
middleName4=?,
|
||||
middleName5=?
|
||||
WHERE
|
||||
id=?
|
||||
|
||||
-- binding parameter [1] as [VARCHAR] - [John]
|
||||
-- binding parameter [2] as [VARCHAR] - [Doe Jr]
|
||||
-- binding parameter [3] as [VARCHAR] - [Flávio]
|
||||
-- binding parameter [4] as [VARCHAR] - [André]
|
||||
-- binding parameter [5] as [VARCHAR] - [Frederico]
|
||||
-- binding parameter [6] as [VARCHAR] - [Rúben]
|
||||
-- binding parameter [7] as [VARCHAR] - [Artur]
|
||||
-- binding parameter [8] as [BIGINT] - [1]
|
||||
|
||||
SELECT
|
||||
p.fullName as fullName3_0_
|
||||
FROM
|
||||
Person p
|
||||
WHERE
|
||||
p.id=?
|
||||
|
||||
-- binding parameter [1] as [BIGINT] - [1]
|
||||
-- extracted value ([fullName3_0_] : [VARCHAR]) - [John Flávio André Frederico Rúben Artur Doe Jr]
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* 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.mapping.generated;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
import org.hibernate.annotations.Generated;
|
||||
import org.hibernate.annotations.GenerationTime;
|
||||
import org.hibernate.dialect.SQLServer2005Dialect;
|
||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||
|
||||
import org.hibernate.testing.RequiresDialect;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
@RequiresDialect(SQLServer2005Dialect.class)
|
||||
public class GeneratedTest extends BaseEntityManagerFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
Person.class
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
//tag::mapping-generated-Generated-persist-example[]
|
||||
Person person = new Person();
|
||||
person.setId( 1L );
|
||||
person.setFirstName( "John" );
|
||||
person.setMiddleName1( "Flávio" );
|
||||
person.setMiddleName2( "André" );
|
||||
person.setMiddleName3( "Frederico" );
|
||||
person.setMiddleName4( "Rúben" );
|
||||
person.setMiddleName5( "Artur" );
|
||||
person.setLastName( "Doe" );
|
||||
|
||||
entityManager.persist( person );
|
||||
entityManager.flush();
|
||||
|
||||
assertEquals("John Flávio André Frederico Rúben Artur Doe", person.getFullName());
|
||||
//end::mapping-generated-Generated-persist-example[]
|
||||
} );
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
//tag::mapping-generated-Generated-update-example[]
|
||||
Person person = entityManager.find( Person.class, 1L );
|
||||
person.setLastName( "Doe Jr" );
|
||||
|
||||
entityManager.flush();
|
||||
assertEquals("John Flávio André Frederico Rúben Artur Doe Jr", person.getFullName());
|
||||
//end::mapping-generated-Generated-update-example[]
|
||||
} );
|
||||
}
|
||||
|
||||
//tag::mapping-generated-Generated-example[]
|
||||
@Entity(name = "Person")
|
||||
public static class Person {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
private String firstName;
|
||||
|
||||
private String lastName;
|
||||
|
||||
private String middleName1;
|
||||
|
||||
private String middleName2;
|
||||
|
||||
private String middleName3;
|
||||
|
||||
private String middleName4;
|
||||
|
||||
private String middleName5;
|
||||
|
||||
@Generated( value = GenerationTime.ALWAYS )
|
||||
@Column(columnDefinition =
|
||||
"AS CONCAT(" +
|
||||
" COALESCE(firstName, ''), " +
|
||||
" COALESCE(' ' + middleName1, ''), " +
|
||||
" COALESCE(' ' + middleName2, ''), " +
|
||||
" COALESCE(' ' + middleName3, ''), " +
|
||||
" COALESCE(' ' + middleName4, ''), " +
|
||||
" COALESCE(' ' + middleName5, ''), " +
|
||||
" COALESCE(' ' + lastName, '') " +
|
||||
")")
|
||||
private String fullName;
|
||||
|
||||
//end::mapping-generated-Generated-example[]
|
||||
public Person() {}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getMiddleName1() {
|
||||
return middleName1;
|
||||
}
|
||||
|
||||
public void setMiddleName1(String middleName1) {
|
||||
this.middleName1 = middleName1;
|
||||
}
|
||||
|
||||
public String getMiddleName2() {
|
||||
return middleName2;
|
||||
}
|
||||
|
||||
public void setMiddleName2(String middleName2) {
|
||||
this.middleName2 = middleName2;
|
||||
}
|
||||
|
||||
public String getMiddleName3() {
|
||||
return middleName3;
|
||||
}
|
||||
|
||||
public void setMiddleName3(String middleName3) {
|
||||
this.middleName3 = middleName3;
|
||||
}
|
||||
|
||||
public String getMiddleName4() {
|
||||
return middleName4;
|
||||
}
|
||||
|
||||
public void setMiddleName4(String middleName4) {
|
||||
this.middleName4 = middleName4;
|
||||
}
|
||||
|
||||
public String getMiddleName5() {
|
||||
return middleName5;
|
||||
}
|
||||
|
||||
public void setMiddleName5(String middleName5) {
|
||||
this.middleName5 = middleName5;
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
//tag::mapping-generated-Generated-example[]
|
||||
}
|
||||
//end::mapping-generated-Generated-example[]
|
||||
}
|
Loading…
Reference in New Issue