How to autogenerate created or modified timestamp field?
You can go with Spring Data JPA, Spring has made it as easy using annotation @CreatedBy, @CreatedDate, @LastModifiedBy, @LastModifiedDate on your fields. You can follow below simple example
// Will need to enable JPA Auditing
@Configuration
@EnableJpaAuditing(auditorAwareRef = "auditorAware")
class JpaConfig {
// Creating a bean of AuditorAwareImpl which will provide currently logged in user
@Bean
public AuditorAware<String> auditorAware() {
return new AuditorAwareImpl();
}
}
// Moving necessary fields to super class and providing AuditingEntityListener entity listner class
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
abstract class Auditable<U> {
@CreatedBy
protected U createdBy;
@CreatedDate
@Temporal(TIMESTAMP)
protected Date createdDate;
@LastModifiedBy
protected U lastModifiedBy;
@LastModifiedDate
@Temporal(TIMESTAMP)
protected Date lastModifiedDate;
// Getters and Setters
}
// Creating implementation of AuditorAware and override its methods to provide currently logged in user
class AuditorAwareImpl implements AuditorAware<String> {
@Override
public String getCurrentAuditor() {
return "Naresh";
// Can use Spring Security to return currently logged in user
// return ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername()
}
}
@Entity
class File extends Auditable<String> {
@Id
@GeneratedValue
private Integer id;
private String name;
private String content;
// Getters and Setters
}
You can read more on my article Spring Data JPA Auditing: Saving CreatedBy, CreatedDate, LastModifiedBy, LastModifiedDate automatically for more details.
You can just create a new Date()
whenever your instance is created, and then update the updated
field whenever the entity gets updated:
private Date created = new Date();
private Date updated = new Date();
@PreUpdate
public void setLastUpdate() { this.updated = new Date(); }
Don't provide a setter for any of these methods, only getters.
In 4.3 Hibernate with JPA, one can use "@CreationTimestamp" and "@UpdateTimestamp" directly in the date fields
CreationTimestamp java doc
UpdateTimestamp java doc
We do this with a PreInsertEventListener and a PreUpdateEventListener :
public class TracabilityListener implements PreInsertEventListener,PreUpdateEventListener {
private void setPropertyState(Object[] propertyStates, String[] propertyNames,String propertyName,Object propertyState) {
for(int i=0;i<propertyNames.length;i++) {
if (propertyName.equals(propertyNames[i])) {
propertyStates[i]=propertyState;
return;
}
}
}
private void onInsert(Object entity,Object[] state, String[] propertyNames) {
if (entity instanceof DomainObject) {
DomainObject domainObject = (DomainObject) entity;
Date date=new Date();
domainObject.setDateCreation(date);
setPropertyState(state, propertyNames, "dateCreation", date);
domainObject.setDateModification(date);
setPropertyState(state, propertyNames, "dateModification", date);
}
}
private void onUpdate(Object entity,Object[] state, String[] propertyNames) {
if (entity instanceof DomainObject) {
DomainObject domainObject = (DomainObject) entity;
Date date=new Date();
setPropertyState(state, propertyNames, "dateCreation", domainObject.getDateCreation());
domainObject.setDateModification(date);
setPropertyState(state, propertyNames, "dateModification", date);
}
}
@Override
public boolean onPreInsert(PreInsertEvent event) {
onInsert(event.getEntity(), event.getState(), event.getPersister().getPropertyNames());
return false;
}
@Override
public boolean onPreUpdate(PreUpdateEvent event) {
onUpdate(event.getEntity(), event.getState(), event.getPersister().getPropertyNames());
return false;
}
}
But if you want your properties to be timestamps, then they should be annotated with
@Temporal(TemporalType.TIMESTAMP)