2020-08-27

Hibernate JPA @ValueGenerationType Example

@ValueGenerationType

The @ValueGenerationType annotation is used to specify that the current annotation type should be used as a generator annotation type.

ValueGenerationType marks an annotation type as a generator annotation type.
Adding a generator annotation to an entity property causes the value of the property to be generated upon insert or update of the owning entity. Not more than one generator annotation may be placed on a given property.

Each generator annotation type is associated with a AnnotationValueGeneration which implements the strategy for generating the value. Generator annotation types may define arbitrary custom attributes, e.g. allowing the client to configure the generation timing (if applicable) or other settings taking an effect on the value generation. The corresponding implementation can retrieve these settings from the annotation instance passed to AnnotationValueGeneration.initialize(java.lang.annotation.Annotation, Class).

Custom generator annotation types must have retention policy RetentionPolicy.RUNTIME.

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;

//Constructors, getters, and setters are omitted for brevity
}

@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";
}
}
When persisting an Event entity, Hibernate generates the following SQL statement:

INSERT INTO Event ("timestamp", id)
VALUES (current_timestamp, 1)
As you can see, the current_timestamp value was used for assigning the timestamp column value.

In-memory-generated values
If the timestamp value needs to be generated in-memory, the following mapping must be used instead:

Example : 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;

//Constructors, getters, and setters are omitted for brevity
}

@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;
}
}
When persisting an Event entity, Hibernate generates the following SQL statement:

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 the timestamp column value.

No comments:

Post a Comment