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类的全路径

标签: none

添加新评论 »