Software Developer
Let’s assume we have the following Post entity:
@Entity(name = "Post")
@Table(name = "post")
public class Post {
@Id
private Long id;
private String title;
private long score;
@Column(
name = "created_on",
nullable = false,
updatable = false
)
private Timestamp createdOn;
@Transient
private String creationTimestamp;
public Post() {
this.createdOn = new Timestamp(
System.currentTimeMillis()
);
}
public String getCreationTimestamp() {
if(creationTimestamp == null) {
creationTimestamp = DateTimeFormatter
.ISO_DATE_TIME.format(
createdOn.toLocalDateTime()
);
}
return creationTimestamp;
}
@Override
public String toString() {
return String.format(
"Post{\n" +
" id=%d\n" +
" title='%s'\n" +
" score=%d\n" +
" creationTimestamp='%s'\n" +
'}', id, title, score, getCreationTimestamp()
);
}
//Getters and setters omitted for brevity
}
The publishing entity has a created characteristic that ought to most effectively be set when the entity is created for the primary time. Any successive update isn't allowed to adjust this database column, consequently, the updatable characteristic of the related @column annotation is ready to false.
@Column(
name = "created_on",
nullable = false,
updatable = false
)
private Timestamp created;
The put-up entity-created attribute is a timestamp that we would need to print in software logs the usage of the iso_date_time date-time formating. To keep away from calculating the string object illustration on every occasion we want to log this entity, the creation timestamp attribute goes to keep this value.
@Transient
private String creationTimestamp;
However, we don’t want this characteristic to be continued. Hence, we want to annotate it with the @brief. This way, hibernate is going to disregard this attribute while translating the entity kingdom changes into a square assertion.
Assuming we have persisted the following entity:
doInJPA(entityManager -> {
Post post = new Post();
post.setId(1L);
post.setTitle("High-Performance Java Persistence");
entityManager.persist(post);
});
When fetching, logging, and modifying this entity:
doInJPA(entityManager -> {
Post post = entityManager.find(Post.class, 1L);
LOGGER.info("Fetched post: {}", post);
post.setScore(12);
});
The following output is obtained:
SELECT p.id AS id1_0_0_,
p.created_on AS created_2_0_0_,
p.score AS score3_0_0_,
p.title AS title4_0_0_
FROM post p
WHERE p.id = 1
-- Fetched post: Post{
id=1
title='High-Performance Java Persistence'
score=0
creationTimestamp='2016-10-10T16:48:25.566'
}
UPDATE post
SET score = 12,
title = 'High-Performance Java Persistence'
WHERE id = 1
As you can see, neither the created nor the creation timestamp are included in the UPDATE SQL statement.
The previous update statement includes all table columns, even if simplest a subset is being changed. Using the same square announcement is useful while the use of JDBC assertion caching. But, if the database desk is closely listed, we don’t need to replace positive index entries which have not been changed, as defined using Markus Winand.
For this reason, Hibernate offers the @DynamicUpdate annotation. All we need to do is to add this annotation at the entity level:
@Entity(name = "Post")
@Table(name = "post")
@DynamicUpdate
public class Post {
//Code omitted for brevity
}
Now, when executing the previous test case which modified the score attribute, the following UPDATE statement is executed:
UPDATE post
SET score = 12,
WHERE id = 1