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.
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
Clone() VS Copy Constructor VS Factory Method
Java Null Check Why Use == Instead of .Equals()
When and Why JPA Entities Should Implement the Serializable Interface
Spring MVC - How to Get All Request Params in a Map in Spring Controller
Using Generics in Spring Data JPA Repositories
Getting Java Version at Runtime
Comparing Two Java.Util.Dates to See If They Are in the Same Day
How Is an Instance Initializer Different from a Constructor
How to Create and Run Apache Jmeter Test Scripts from a Java Program
How to Format Decimals in a Currency Format
How to Make My Arraylist Thread-Safe? Another Approach to Problem in Java
Difference Between Java Se/Ee/Me
How to Get the Size of an Array, a Collection, or a String in Java
How to Make Threadpoolexecutor's Submit() Method Block If It Is Saturated