hibernate中的PreInsert和PreUpdate事件监听器

我使用了PreInsertEventListenerPreInsertEventListener事件侦听器在表中插入创建日期和更新日期。
我面临的问题是,当我在数据库中保存实体时创建的日期无法插入表中,与更新记录时插入更新日期相同,它也不会插入更新日期。

我的代码示例如下所示:

听众课程:

 public class PreInsertListener implements PreInsertEventListener, PreUpdateEventListener { @Override public boolean onPreInsert(PreInsertEvent arg0) { City.class.cast(arg0.getEntity()).setCreated_date(new Date()); return false; } @Override public boolean onPreUpdate(PreUpdateEvent arg0) { System.out.println("Update event......"); City.class.cast(arg0.getEntity()).setUpdated_date(new Date()); return false; } } 

Hibernate Connection类:

 public class HibernateUtil 

{

 private static final SessionFactory sessionFactory; static { try { AnnotationConfiguration config = new AnnotationConfiguration(); config.setListener("pre-insert", new PreInsertListener()); config.setListener("pre-update", new PreInsertListener()); sessionFactory = config.configure().buildSessionFactory();; } catch (Throwable ex) { System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } } 

DAO中的实体保存和更新方法:

 public Long saveCity(String cityName) { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction transaction = null; Long cityId = null; try { transaction = session.beginTransaction(); City city = new City(); city.setName(cityName); cityId = (Long) session.save(city); //session.flush(); transaction.commit(); } catch (HibernateException e) { transaction.rollback(); e.printStackTrace(); } finally { session.close(); } return cityId; } public void updateCity(Long cityId, String cityName) { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); City city = (City) session.get(City.class, cityId); city.setName(cityName); session.update(city); //session.flush(); transaction.commit(); } catch (HibernateException e) { transaction.rollback(); e.printStackTrace(); } finally { session.close(); } } 

我的测试类:

 public class Main { public static void main(String[] args) { CityDAO cityDAO = new CityDAO(); long cityId1 = cityDAO.saveCity("New York"); cityDAO.updateCity(cityId1, "Paris"); } } 

如果我使用session.flush() ,它将插入创建和更新的日期,但每次调用flush方法时都会执行更新的查询。 目前我评论代码调用session.flush()方法在代码中显示。

这个问题的解决方案是什么?

这样做

 public class PreInsertListener implements PreInsertEventListener, PreUpdateEventListener { @Override public boolean onPreInsert(PreInsertEvent arg0) { if(arg0.getEntity() instanceof City){ City city = (City)arg0.getEntity(); city.setCreated_date(new Date()); } return false; } @Override public boolean onPreUpdate(PreUpdateEvent arg0) { if(arg0.getEntity() instanceof City){ City city = (City)arg0.getEntity(); city.setCreated_date(new Date()); } return false; } } 

我创建了Interceptor,用Hibernate EmptyInterceptor扩展它。
覆盖方法onSave()将在保存对象时调用,该对象尚未保存到数据库中而onFlushDirty()在更新对象时调用,该对象尚未更新到数据库中。
在这个函数中,我通过其名称检查我的方法,其中我必须在创建或更新时设置日期。
这是onFlushDirty()方法的示例代码。

 public boolean onFlushDirty(Object entity,Serializable id,Object[] currentState, Object[] previousState,String[] propertyNames, Type[] types) { if ( entity instanceof City ) { for ( int i=0; i < propertyNames.length; i++ ) { if ( "lastUpdatedOn".equals( propertyNames[i] ) ) { currentState[i] = new Date(); return true; } } } return false; } 

这里lastUpdatedOn是我的方法名称,它设置了更新的记录日期。

onSave()方法:

 public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { if ( entity instanceof City) { for ( int i=0; i 

这里createdOn是设置记录创建日期的方法。

使用此拦截器类扩展您的POJO类。

我最近在集成Spring4和Hibernate5时遇到了同样的问题。 这是我的BaseEntity类。

 @MappedSuperclass public class BaseEntity implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column(nullable = false, updatable = false) private Date createDate; @Column(nullable = false) private Date modifyDate; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } public Date getModifyDate() { return modifyDate; } public void setModifyDate(Date modifyDate) { this.modifyDate = modifyDate; } } 

首先,您需要定义EntityListener类。

 public class EntityListener implements PreInsertEventListener, PreUpdateEventListener { private static final String CREATE_DATE_PROPERTY = "createDate"; private static final String MODIFY_DATE_PROPERTY = "modifyDate"; @Override public boolean onPreInsert(PreInsertEvent event) { if (event.getEntity() instanceof BaseEntity){ //property name of entity String[] propertyNames = event.getPersister().getEntityMetamodel().getPropertyNames(); //property value of entity Object[] state = event.getState(); for (int i = 0; i < propertyNames.length ; i ++) { if (CREATE_DATE_PROPERTY.equals(propertyNames[i]) || MODIFY_DATE_PROPERTY.equals(propertyNames[i])){ state[i] = new Date(); } } } return false; } @Override public boolean onPreUpdate(PreUpdateEvent event) { if (event.getEntity() instanceof BaseEntity){ //property name of entity String[] propertyNames = event.getPersister().getEntityMetamodel().getPropertyNames(); //property value of entity Object[] state = event.getState(); for (int i = 0; i < propertyNames.length ; i ++) { if (MODIFY_DATE_PROPERTY.equals(propertyNames[i])){ state[i] = new Date(); } } } return false; } } 

然后,您应该注册实体事件侦听器。

 @SuppressWarnings("unchecked") @Component public class EntityEventListenerRegistry { @Autowired private SessionFactory sessionFactory; /** * EventListenerRegistry:http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#annotations-jpa-entitylisteners */ @PostConstruct public void registerListeners(){ EventListenerRegistry eventListenerRegistry = ((SessionFactoryImplementor) sessionFactory).getServiceRegistry().getService(EventListenerRegistry.class); eventListenerRegistry.prependListeners(EventType.PRE_INSERT, EntityListener.class); eventListenerRegistry.prependListeners(EventType.PRE_UPDATE, EntityListener.class); } } 

它工作得很好,我希望它对你有所帮助。