`@Entity(name = "Event") public static class Event {
2.3.18. Generated properties
<div class="paragraph">
Generated properties are properties that have their values generated by the database.
Typically, Hibernate applications needed to `refresh` objects that contain any properties for which the database was generating values.
Marking properties as generated, however, lets the application delegate this responsibility to Hibernate.
When Hibernate issues an SQL INSERT or UPDATE for an entity that has defined generated properties, it immediately issues a select to retrieve the generated values.
</div>
<div class="paragraph">
Properties marked as generated must additionally be _non-insertable_ and _non-updateable_.
Only `@Version` and `@Basic` types can be marked as generated.
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">`never` (the default)</dt>
<dd>
the given property value is not generated within the database.
</dd>
<dt class="hdlist1">`insert`</dt>
<dd>
the given property value is generated on insert, but is not regenerated on subsequent updates. Properties like _creationTimestamp_ fall into this category.
</dd>
<dt class="hdlist1">`always`</dt>
<dd>
the property value is generated both on insert and on update.
</dd>
</dl>
</div>
<div class="paragraph">
To mark a property as generated, use The Hibernate specific `@Generated` annotation.
</div>
<div class="sect4">
##### `@CreationTimestamp` annotation
<div class="paragraph">
The `@CreationTimestamp` annotation instructs Hibernate to set the annotated entity attribute with the current timestamp value of the JVM
when the entity is being persisted.
</div>
<div class="paragraph">
The supported property types are:
</div>
<div class="ulist">
java.util.Date
java.util.Calendar
java.sql.Date
java.sql.Time
java.sql.Timestamp
</div>Example 55. `@CreationTimestamp` mapping example@Id @GeneratedValue private Long id; @Column(name = "`timestamp`") @CreationTimestamp private Date timestamp; public Event() {} public Long getId() { return id; } public Date getTimestamp() { return timestamp; }
}`</pre> </div> </div> </div> </div>
When the
Event
entity is persisted, Hibernate is going to populate the underlyingtimestamp
column with the current JVM timestamp value:</div>
Example 56. `@CreationTimestamp` persist example`Event dateEvent = new Event( ); entityManager.persist( dateEvent );`
`INSERT INTO Event("timestamp", id) VALUES (?, ?)
-- binding parameter [1] as [TIMESTAMP] - [Tue Nov 15 16:24:20 EET 2016] -- binding parameter [2] as [BIGINT] - [1]`</pre> </div> </div> </div> </div> </div>
@ValueGenerationType
meta-annotationHibernate 4.3 introduced the
@ValueGenerationType
meta-annotation, which is a new approach to declaring generated attributes or customizing generators.</div>
@Generated
has been retrofitted to use the@ValueGenerationType
meta-annotation. But@ValueGenerationType
exposes more features than what@Generated
currently supports, and, to leverage some of those features, you’d simply wire up a new generator annotation.</div>
As you’ll see in the following examples, the
@ValueGenerationType
meta-annotation is used when declaring the custom annotation used to mark the entity properties that need a specific generation strategy. The actual generation logic must be implemented in class that implements theAnnotationValueGeneration
interface.</div>
Database-generated values
For example, let’s say we want the timestamps to be generated by calls to the standard ANSI SQL function
current_timestamp
(rather than triggers or DEFAULT values):</div>
Example 57. A `ValueGenerationType` mapping for database generation`@Entity(name = "Event") public static class Event {
@Id @GeneratedValue private Long id; @Column(name = "`timestamp`") @FunctionCreationTimestamp private Date timestamp; public Event() {} public Long getId() { return id; } public Date getTimestamp() { return timestamp; }
}
@ValueGenerationType(generatedBy = FunctionCreationValueGeneration.class) @Retention(RetentionPolicy.RUNTIME) public @interface FunctionCreationTimestamp {}
public static class FunctionCreationValueGeneration
implements AnnotationValueGeneration<FunctionCreationTimestamp> { @Override public void initialize(FunctionCreationTimestamp annotation, Class<?> propertyType) { } /** * Generate value on INSERT * @return when to generate the value */ public GenerationTiming getGenerationTiming() { return GenerationTiming.INSERT; } /** * Returns null because the value is generated by the database. * @return null */ public ValueGenerator<?> getValueGenerator() { return null; } /** * Returns true because the value is generated by the database. * @return true */ public boolean referenceColumnInSql() { return true; } /** * Returns the database-generated value * @return database-generated value */ public String getDatabaseGeneratedReferencedColumnValue() { return "current_timestamp"; }
}`</pre> </div> </div> </div> </div>
When persisting an
Event
entity, Hibernate generates the following SQL statement:</div>
`INSERT INTO Event ("timestamp", id) VALUES (current_timestamp, 1)`
As you can see, the
current_timestamp
value was used for assigning thetimestamp
column value.</div> </div>
In-memory-generated values
If the timestamp value needs to be generated in-memory, the following mapping must be used instead:
</div>
Example 58. A `ValueGenerationType` mapping for in-memory value generation`@Entity(name = "Event") public static class Event {
@Id @GeneratedValue private Long id; @Column(name = "`timestamp`") @FunctionCreationTimestamp private Date timestamp; public Event() {} public Long getId() { return id; } public Date getTimestamp() { return timestamp; }
}
@ValueGenerationType(generatedBy = FunctionCreationValueGeneration.class) @Retention(RetentionPolicy.RUNTIME) public @interface FunctionCreationTimestamp {}
public static class FunctionCreationValueGeneration
implements AnnotationValueGeneration<FunctionCreationTimestamp> { @Override public void initialize(FunctionCreationTimestamp annotation, Class<?> propertyType) { } /** * Generate value on INSERT * @return when to generate the value */ public GenerationTiming getGenerationTiming() { return GenerationTiming.INSERT; } /** * Returns the in-memory generated value * @return {@code true} */ public ValueGenerator<?> getValueGenerator() { return (session, owner) -> new Date( ); } /** * Returns false because the value is generated by the database. * @return false */ public boolean referenceColumnInSql() { return false; } /** * Returns null because the value is generated in-memory. * @return null */ public String getDatabaseGeneratedReferencedColumnValue() { return null; }
}`</pre> </div> </div> </div> </div>
When persisting an
Event
entity, Hibernate generates the following SQL statement:</div>
`INSERT INTO Event ("timestamp", id) VALUES ('Tue Mar 01 10:58:18 EET 2016', 1)`
As you can see, the
new Date()
object value was used for assigning thetimestamp
column value.</div> </div> </div> </div>