Hibernate 使用Event Listener 实现createDate和modifiedDate自动生成
作者:Rui 发布时间:August 18, 2016 分类:JAVA,Hibernate 浏览:837
程序中我们经常会需要实现记录实体的创建时间和修改时间,如果我们使用Hibernate JPA的API,可以借助注解@PrePersist和@PreUpdate来实现,但是使用Hibernate 经典的session的API这些是不起作用的,但Hibernate提供Event Listener的方式可以供我们来添加Hibernate保存,更新,删除的监听,我们可以利用PRE_INSERT和PRE_UPDATE来实现该需求。
使用JPA注解实现代码示例:
@PrePersist
public void onSave() {
this.createDate = new Date();
this.modifiedDate = new Date();
}
@PreUpdate
public void onUpdate() {
this.modifiedDate = new Date();
}
使用Hibernate Event Listener 实现SaveorUpdateDateListener 监听器,需要注意的是我们必须修改EntityMetamodel中的属性值才能够修改生成sql中的值,因为Hibernate为了解析prepared statement,会将实体的值全部的放到事件中的一个state数组中。所以我们单纯的修改entity的属性,并不会起作用。
/**
* using HIbernate SaveOrUpdateEventListener to init createDate and modifiedDate value
*/
public class SaveorUpdateDateListener implements PreUpdateEventListener, PreInsertEventListener {
@Override
public boolean onPreInsert(PreInsertEvent event) {
NonIdentifierAttribute[] properties = event.getPersister().getEntityMetamodel().getProperties();
Object[] state = event.getState();
for (int i = 0; i < properties.length; i++) {
if (properties[i].getName().equals("createDate")) {
state[i] = new Date();
}
if (properties[i].getName().equals("modifiedDate")) {
state[i] = new Date();
}
if (properties[i].getName().equals("deleted")) {
state[i] = false;
}
}
return false;
}
@Override
public boolean onPreUpdate(PreUpdateEvent event) {
NonIdentifierAttribute[] properties = event.getPersister().getEntityMetamodel().getProperties();
Object[] state = event.getState();
for (int i = 0; i < properties.length; i++) {
if (properties[i].getName().equals("modifiedDate")) {
state[i] = new Date();
}
}
return false;
}
}
注册Event Listener,本例使用Integrator 附加Event Listener的配置,在项目中,也可以修改Hibernate配置文件添加Event Listener的配置
/**
* config hibernate event listener with Hibernate SPI Integrator
*/
public class ServerHibernateIntegrator implements Integrator {
@Override
public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService(EventListenerRegistry.class);
SaveorUpdateDateListener listener = new SaveorUpdateDateListener();
eventListenerRegistry.appendListeners(EventType.PRE_INSERT, listener);
eventListenerRegistry.appendListeners(EventType.PRE_UPDATE, listener);
}
@Override
public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
}
}
因为hibernate Integrator 使用SPI的方式加载,所以还需要在程序中META-INF/services下创建名为org.hibernate.integrator.spi.Integrator的文件,其内容填写为ServerHibernateIntegrator类的全路径