2011-02-18 84 views
2

在将我的实体写入数据库之前,我在Hibernate中使用PreInsert和PreUpdate EventListeners来设置“创建”和“更新”时间戳的值。问题是下次Hibernate读取然后刷新实体时,Hibernate会看到更改的时间戳,并认为即使没有其他更改,对象也需要更新。因此,听众再次被解雇,更新发生,并且一遍又一遍。通过EventListener更新Hibernate实体

理想情况下,我希望能够在没有Hibernate的情况下分配这些时间戳,认为下次刷新对象时脏了。处理这个问题的最佳解决方案是什么?我假设我可以覆盖脏检查,但我想看看别人做了什么。

下面是参考一些示例代码(这只是示例代码,所以没有必要吹毛求疵):

@Entity 
class MyEntity { 
    @Id 
    Long id = Long.valueOf(1); 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date created; 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date updated; 

    @Override 
    public void setCreated(Date created) { 
     this.created = created; 
    } 

    @Override 
    public void setUpdated(Date updated) { 
     this.updated = updated; 
    } 
} 

public class PreInsertAndUpdateEventListener implements PreInsertEventListener, PreUpdateEventListener { 
    @Override 
    public boolean onPreUpdate(PreUpdateEvent event) { 
     MyEntity.class.cast(event.getEntity()).setUpdated(new Date()); 
     return false; 
    } 

    @Override 
    public boolean onPreInsert(PreInsertEvent event) { 
     MyEntity.class.cast(event.getEntity()).setCreated(new Date()); 
     return false; 
    } 
} 

public void updatedTest() { 
    Session session = sessionFactory.openSession(); 
    Transaction t = session.beginTransaction(); 

    MyEntity p = new MyEntity(); 
    Serializable id = session.save(p); 
    session.flush(); 

    for (int i = 0; i < 5; i++) { 
     p = (MyEntity) session.get(MyEntity.class, id); 
     session.update(p); 
     session.flush(); // Update always fires here 
    } 

    t.commit(); 
    session.close(); 
} 
+0

http://stackoverflow.com/questions/221611/creation-timestamp-and-last-update-timestamp-with-hibernate-and-mysql做到像这里和事件不应该被调用。 – dzezzz 2016-06-13 12:52:50

回答

0

我决定采取的解决方案是更新Hibernate的状态相匹配的实体每次我的通过事件监听器修改实体。实施看起来是这样的:

StandardProperty[] properties = event.getPersister().getEntityMetamodel().getProperties(); 
Object[] state = event.getState(); 

for (int i = 0; i < properties.length; i++) { 
    if (properties[i].getName().equals("updated")) { 
     state[i] = timestamp; 
     break; 
    } 
}