im trying to create a spring (3.1) and hibernate (3.6.10) web application and have a problem with hibernation events. I applied my own DefaultSaveOrUpdateEventListener to update / create dateCreated and lastUpdated date, which is called for every .saveOrUpdate () event. So far so good.
Should this listener also be called on .save () or .update () events? Or am I missing something?
LISTENER:
public class SaveOrUpdateDateListener extends DefaultSaveOrUpdateEventListener { private static final long serialVersionUID = 1L; private static Logger log = Logger.getLogger(SaveOrUpdateDateListener.class); @Override public void onSaveOrUpdate(SaveOrUpdateEvent event) { log.debug("Entered onSaveOrUpdate()"); if (event.getObject() instanceof BaseDomain) { BaseDomain record = (BaseDomain) event.getObject(); record.setDateUpdated(new Date()); if (record.getDateCreated() == null) { record.setDateCreated(new Date()); } } super.onSaveOrUpdate(event); } }
Sleep configuration (partially):
<sesssion-factory> <event type="save-update"> <listener class="net.test.listener.hibernate.SaveOrUpdateDateListener"/> <listener class="org.hibernate.event.def.DefaultSaveOrUpdateEventListener"/> </event> </session-factory>
Examples of dao methods ( doesn't work ):
@Autowired private SessionFactory sessionFactory; @Override public void add(Registration registration) { sessionFactory.getCurrentSession().save(registration); } @Override public void update(Registration registration) { sessionFactory.getCurrentSession().update(registration); }
Examples of dao methods ( works ):
@Autowired private SessionFactory sessionFactory; @Override public void add(Registration registration) { sessionFactory.getCurrentSession().saveOrUpdate(registration); } @Override public void update(Registration registration) { sessionFactory.getCurrentSession().saveOrUpdate(registration); }
Edit
After I decided not to use saveOrUpdate, I hopefully solved my problem using the base class as follows:
@MappedSuperclass public class BaseDomain { @Id @GeneratedValue protected Integer id; @Column(nullable=false) protected Timestamp dateCreated; @Column(updatable = false, insertable = false, columnDefinition = "timestamp default current_timestamp on update current_timestamp") @Generated(GenerationTime.ALWAYS) protected Timestamp dateUpdated; protected BaseDomain() { this.dateCreated = new Timestamp(System.currentTimeMillis()); } public Integer getId() { return id; } protected void setId(Integer id) { this.id = id; } public Timestamp getDateCreated() { return dateCreated; } public Date getDateUpdated() { return dateUpdated; } }
Since current_timestamp can only be used once per table (mysql constraint), I tried to create a dateCreated construct through the constructor.