2011-02-18 79 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; 
    } 
}