这是一个很好的问题,这是简短的答案: Hibernate-Session有一种方法 。isDirty()
带有示例的长答案(测试用例 1):
如果你在Hibernate之上使用Seam/POJO/JPA,你想知道哪些实体在调用之前是脏的-即知道Hibernate会为哪些实体发出更新声明--并对这些记录应用一些更改(设置一些值,例如谁更改了记录等等)。entityManager.flush()
您知道休眠会话有一个方法,但在某些情况下这还不够。isDirty()
您可以在持久性.xml文件中注册一个休眠拦截器:
<property name="hibernate.ejb.interceptor" value="path.to.MyInterceptor" />
并拦截该方法并将脏对象保存在地图中,但是我以后如何访问此地图?我在运行时无法访问拦截器(以便我可以调用),你有这个:onFlushDirty(...)
interceptor.getDirtyEntities()
public class MyInterceptor extends EmptyInterceptor {
private Map<IdentityKey,Object> dirtyEntitiesMap = new HashMap<IdentityKey,Object>();
@Override
public boolean onFlushDirty(Object entity, Serializable id,
Object[] currentState, Object[] previousState,
String[] propertyNames, Type[] types) {
dirtyEntitiesMap.put(new IdentityKey(id, entity.getClass()), entity);
return super.onFlushDirty(entity, id, currentState, previousState, propertyNames, types);
}
...
}
SOLVER 此测试用例:如果您只需要更新哪些实体,则无需知道这些实体发生了变化。您可以在方法中添加代码(填充更改代码的用户)。脏的实体将被相应地修改,那些不脏的实体将不会调用此方法,因为没有什么可更新的(并且Hibernate将检测到这一点)。您可以在可能相同的方法中对新实体执行相同的操作。您可以使用两者为同一方法批注。@PreUpdate
@PrePersist
如果您还需要记录哪些字段已更改,我建议您先查看Envers。