返回Hibernate envers使用修改后的标志进行审计修订

时间:2015-07-02 15:19:59

标签: java audit hibernate-envers

我在我的应用中使用Hibernate Envers来跟踪我的实体的所有字段中的更改。 我使用@Audited(withModifiedFlag = true)注释来完成它。

记录已在数据库中正确记录,_mod字段正确指示已更改的字段。

我希望从某个实体获得特定修订,以及哪些字段已更改的信息。我使用了以下方法:

        List<Object[]> results = reader.createQuery()  
            .forRevisionsOfEntity(this.getDao().getClazz(), false, true)  
            .add(AuditEntity.id().eq(id))  
            .getResultList(); 

此方法返回一个对象数组的列表,其中我的实体作为第一个元素。

问题是返回的实体没有关于更改字段的任何信息。 所以,我的问题是:如何获取有关已更改字段的信息?

1 个答案:

答案 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;
}