Creation Timestamp and Last Update Timestamp with Hibernate and MySQL

Missing @CreationTimestamp and @UpdateTimestamp after generating persistence mapping by database schema

You can try using scripted extensions to Generate a Java POJO entity class for the selected table in Project tool window. In the dialog that opens, specify the directory in which the .java class file should be generated. Please see attached screenshot. You can customize the script to generate any text. See also these examples and Generate simple classes from database objects in DataGrip blog post.

Sample Image

Update timestamp for each row in Hibernate

There are many ways to achieve this goal.

@EntityListener

You can have an @Embeddable to store the audit properties:

@Embeddable
public class Audit {

@Column(name = "created_on")
private LocalDateTime createdOn;

@Column(name = "updated_on")
private LocalDateTime updatedOn;

//Getters and setters omitted for brevity
}

Which requires an EntityListener that looks as follows:

public class AuditListener {

@PrePersist
public void setCreatedOn(Auditable auditable) {
Audit audit = auditable.getAudit();

if(audit == null) {
audit = new Audit();
auditable.setAudit(audit);
}

audit.setCreatedOn(LocalDateTime.now());
}

@PreUpdate
public void setUpdatedOn(Auditable auditable) {
Audit audit = auditable.getAudit();

audit.setUpdatedOn(LocalDateTime.now());
}
}

Your entities will have to implement the Audit interface:

public interface Auditable {

Audit getAudit();

void setAudit(Audit audit);
}

And the entities will look like this:

@Entity(name = "Tag")
@Table(name = "tag")
@EntityListeners(AuditListener.class)
public class Tag implements Auditable {

@Id
private String name;

@Embedded
private Audit audit;

//Getters and setters omitted for brevity
}

This is a very elegant solution since it extracts the audit logic from the main entity mapping.

@PrePersist and @PreUpdate

You can use the @PrePersist and @PreUpdate JPA annotations as well:

@Embeddable
public class Audit {

@Column(name = "created_on")
private LocalDateTime createdOn;

@Column(name = "updated_on")
private LocalDateTime updatedOn;

@PrePersist
public void prePersist() {
createdOn = LocalDateTime.now();
}

@PreUpdate
public void preUpdate() {
updatedOn = LocalDateTime.now();
}

//Getters and setters omitted for brevity
}

and add the Audit embeddable to the entity like this:

@Entity(name = "Tag")
@Table(name = "tag")
public class Tag {

@Id
private String name;

@Embedded
private Audit audit = new Audit();

//Getters and setters omitted for brevity
}

Hibernate-specific @CreationTimestamp and @UpdateTimestamp

@CreationTimestamp
@Column(name = "created_on")
private Date createdOn;

@Column(name = "updated_on")
@UpdateTimestamp
private Date updatedOn;

That's it!

Now, related to your comment:

But what I get is that when I update one row, the timestamps for all of the rows updated, so all of the timestamps in the table are always the same. What am I doing wrong here?

The timestamp will only be updated for the entity that gets modified, not for all rows. It does not make any sense to update the timestamp of all rows when only a single row gets modified. Otherwise, why would you have that column on the row itself?

If you want the last modification timestamp, just run a query like this:

SELECT MAX(updated_on)
FROM tags

Generate a timestamp in a column while inserting in Spring, Hibernate and PostgreSQL

The prePersist and other @createTimeStamp hooks works if you are making inserts from within the application by using the JPA or native hibernate methods. If you simply run inserts from outside your application context, there is no way hibernate would come to know what DMLs are running and hence the hooks will never be called. If you want that even from outside when you run the inserts, the timestamp for create should auto populate, you would need to add table level DDL instructions.
Eg: ALTER TABLE mytable ALTER COLUMN datecreated SET DEFAULT now();

Now as to auto DDL ability of hibernate, the xml property <property name="hibernate.hbm2ddl.auto">create</property> generates DDL from entity definitions but not DMLs. So, you can also embed the DEFAULT timestamp value in column definition of the concerned entity as so or similar:

@Column(name="datecreated", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")

This will ensure that when the table is created, the definition is applied using the auto DDL property of hibernate settings.

Hope this clarifies

Last update timestamp with JPA

Use @PrePersist and @PreUpdate annotations and write your own event listener.

Take a look at this answer for details. It's tagged as Hibernate but is applicable to any JPA provider.



Related Topics



Leave a reply



Submit