Hibernate Envers:使用集合属性检索实体的正确修订版

时间:2012-04-12 09:41:30

标签: java hibernate hibernate-envers

我有两个经审计的实体,A和B.实体A包含实体B的集合(注释为一对多关系)。将新的A实例插入数据库时​​,A和B的所有行都处于同一版本(让我们说修订版1)。然后,A上有一个更新,它只影响实体B的实例。因此,在更新之后,实体A仍处于修订版1,而B的实体处于修订版2(包括审计表中的MOD条目) 。在版本3中,实体A被删除。因为实体B的集合用@Cascade注释,所以也删除属于A的实体B.

鉴于这种情况,如何使用Envers创建审计查询,获取实体A的实例以及更新后的实体B的修订版2?当我查询实体A的所有修订时,我要么得到A的已删除实体,该实体不包含B(修订版3)的实体,要么我得到修订版1的A,其中包含修订版1的B实体。

使用Hibernate 3.6,如果有帮助的话。

3 个答案:

答案 0 :(得分:2)

如果您在修订版2中阅读实体A,您将获得正确的数据。

目前无法获得实体或相关实体发生变化的修订清单(就像您的情况一样 - 第2版仅在B中更改,而不在a中)。

答案 1 :(得分:1)

我通过在我的A实体上添加隐藏的lastUpdated日期字段解决了类似的问题。

@Entity
public class A {
    private Date lastModified;
    @OneToMany(mappedBy = "a", cascade = CascadeType.ALL )
    private List<B> blist;
    public void touch(){
        lastModified=new Date();
    }
}

然后在相关实体(比如你B字段)中,我添加了以下内容:

public class B {
    @ManyToOne
    private A a; 

    @PreUpdate
    public void ensureParentUpdated(){
        if(a!=null){
            a.touch();
        }
    }
}

这确保只要将修订添加到B,就会将修订添加到A,即使它需要许多实体中的自定义代码。

在你的情况下,这将确保A的历史记录实际上包含B的修订版。这样你只需要一个查询来获得整个A,Bs图的所有修订

答案 2 :(得分:0)

在Hibernate中,我们可以通过指定lazy来控制子项的加载。因此,您需要在hibernate配置中将以下行添加到类定义中,以便在读/写情况下加载所有关联。

<cache usage="read-write"/>

如果您已标记 CacheMode.REFRESH ,则会将项目写入二级缓存。不要从二级缓存中读取。

如果您在父母加载孩子时没有遇到任何问题,您可以转为懒惰,这将返回更新的信息。