我在我的应用中使用Hibernate Envers来跟踪我的实体的所有字段中的更改。 我使用@Audited(withModifiedFlag = true)注释来完成它。
记录已在数据库中正确记录,_mod字段正确指示已更改的字段。
我希望从某个实体获得特定修订,以及哪些字段已更改的信息。我使用了以下方法:
List<Object[]> results = reader.createQuery()
.forRevisionsOfEntity(this.getDao().getClazz(), false, true)
.add(AuditEntity.id().eq(id))
.getResultList();
此方法返回一个对象数组的列表,其中我的实体作为第一个元素。
问题是返回的实体没有关于更改字段的任何信息。 所以,我的问题是:如何获取有关已更改字段的信息?
答案 0 :(得分:3)
我知道这个问题现在有点老了,但我试图这样做,并没有找到任何答案。
似乎没有很好的方法来实现这一目标,但这就是我如何去实现它。
首先,您需要使用投影,这些投影不再为您提供已为您映射的漂亮实体模型。您仍然会返回一个对象数组,但数组中的每个对象都对应于您添加的每个投影(按顺序)。
final List<Object[]> resultList = reader.createQuery()
.forRevisionsOfEntity(this.getDao().getClazz(), false, true)
// if you want revision properties like revision number/type etc
.addProjection(AuditEntity.revisionNumber())
// for your normal entity properties
.addProjection(AuditEntity.id())
.addProjection(AuditEntity.property("title")) // for each of your entity's properties
// for the modification properties
.addProjection(new AuditProperty<Object>(new ModifiedFlagPropertyName(new EntityPropertyName("title"))))
.add(AuditEntity.id().eq(id))
.getResultList();
然后,您需要手动映射每个结果。这部分取决于您,但我使用单独的类作为修订模型,因为它包含正常实体数据的额外数据。如果你想要,你可以通过实体类的@Transient属性实现这一点。
final List<MyEntityRevision> results = resultList.stream().map(this::transformRevisionResult)
.collect(Collectors.toList());
private MyEntityRevision transformRevisionResult(Object[] revisionObjects) {
final MyEntityRevision rev = new MyEntityRevision();
rev.setRevisionNumber((Integer) revisionObjects[0]);
rev.setId((Long) revisionObjects[1]);
rev.setTitle((String) revisionObjects[2]);
rev.setTitleModified((Boolean) revisionObjects[3]);
return rev;
}