我在Hibernate中使用PreInsert和PreUpdate EventListeners在将我的实体写入数据库之前设置“created”和“updated”时间戳的值。问题是下次Hibernate读取然后刷新实体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 :(得分: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;
}
}