Issue
Hi everyone I'm having some problems with the updated_at
column in my database. I'm using hibernate and when I update a model, everything works fine except for the @preUpdate
method. All my application models are extending this base model:
@MappedSuperclass
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@Access(AccessType.PROPERTY)
public class BaseModel implements Serializable {
// VARIABLES ---------------------------------------------------------------
private Integer globalKey;
private Integer id;
private Date createdAt;
private Date updatedAt;
private Date deletedAt;
private User createUser;
private User updateUser;
private User deleteUser;
// CONSTRUCTORS ------------------------------------------------------------
// GETTERS AND SETTERS -----------------------------------------------------
// [hashCode, equals and toString methods] ---------------------------------
@PrePersist
protected void onCreate() {
createdAt = new Date();
}
@PreUpdate
protected void onUpdate() {
updatedAt = new Date();
}
}
And this is the method in the DAO for the update:
public MYOBJECT updateEntity(MYOBJECT entity, User updateUser) throws Exception {
entity.setUpdateUser(updateUser);
sessionFactory.getCurrentSession().update(entity);
return entity;
}
Am I missing something? In my database I see:
---------------------------------------------
| id | updated_at | id_user_update |
| 1 | NULL | 1 |
---------------------------------------------
Solution
I've found the answer to my problem here.
But just a little bit modified... Here is my code:
First of all I've removed from the BaseModel
class these two methods:
@PrePersist
protected void onCreate() {
createdAt = new Date();
}
@PreUpdate
protected void onUpdate() {
updatedAt = new Date();
}
Then I've created a BaseTimestamps
interface, used to set up my createdAt and updatedAt variables
public interface BaseTimestamps {
/**
* On create event.
* used to setup a the creation variable.
*
* @param createdAt
*/
void setCreatedAt(Date createdAt);
/**
* On update event.
* used to setup a the update variable.
*
* @param updatedAt
*/
void setUpdatedAt(Date updatedAt);
}
Finally I've created two listeners for the hibernate session factory in the hibernate.cfg.xml
file.
// SAVE LISTENER
public class SaveListener extends DefaultSaveEventListener {
@Override
public void onSaveOrUpdate(SaveOrUpdateEvent event) {
if (event.getObject() instanceof BaseTimestamps) {
BaseTimestamps record = (BaseTimestamps) event.getObject();
record.setCreatedAt(new Date());
}
super.onSaveOrUpdate(event);
}
}
// UPDATE LISTENER
public class UpdateListener extends DefaultUpdateEventListener {
@Override
public void onSaveOrUpdate(SaveOrUpdateEvent event) {
if (event.getObject() instanceof BaseTimestamps) {
BaseTimestamps record = (BaseTimestamps) event.getObject();
record.setUpdatedAt(new Date());
}
super.onSaveOrUpdate(event);
}
}
And here is my hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="my.package.MyModel"/>
// ............................
<mapping class="my.package.OtherModel"/>
<event type="save">
<listener class="my.package.SaveListener"/>
</event>
<event type="update">
<listener class="my.package.UpdateListener"/>
</event>
</session-factory>
</hibernate-configuration>
When I perform creation or updates, everything works fine and I see in my database the correct values.
Answered By - IlGala
Answer Checked By - Marilyn (JavaFixing Volunteer)