【问题标题】:Hibernate Envers: Retrieving the right revisions of an entity with a collection propertyHibernate Envers:检索具有集合属性的实体的正确修订
【发布时间】:2012-04-24 15:40:33
【问题描述】:

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

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

如果有帮助,请使用 Hibernate 3.6。

【问题讨论】:

标签: java hibernate hibernate-envers


【解决方案1】:

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

<cache usage="read-write"/>

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

如果您在作为父母的时候加载孩子没有问题,您可以转为惰性,这将返回更新的信息。

【讨论】:

  • 你没有理解我的问题,是吗?
  • 我试图从这个问题中理解,但如果你认为我反过来理解它..那么请你尽可能简短地表达出来。
【解决方案2】:

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

目前无法获取实体或相关实体更改的修订列表(如您的情况 - 修订版 2 仅在 B 中进行更改,而不是在 a 中)。

【讨论】:

  • 我尝试在版本 2 中获取 A,但随后审计查询的结果列表为空。我认为这种行为是正确的,因为当然,审计表中没有 A 修订版 2 的条目。
  • 嗯,不,这很奇怪,在修订版 2 中存在实体 A。啊!也许您使用了错误类型的查询。一种是查找在给定修订版中修改的实体(因此在 rev2 时,A 未修改),另一种是在给定 rev 时查找实体(然后 A 在 rev2 时存在)。
  • 谢谢,就是这样。使用 forEntitiesAtRevision() 而不是 forRevisionsOfEntity() 解决了我的问题。
【解决方案3】:

我通过在您的 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 图表的所有修订

【讨论】:

    猜你喜欢
    • 2020-03-09
    • 2017-10-09
    • 1970-01-01
    • 2017-11-28
    • 2021-04-06
    • 2019-08-20
    • 1970-01-01
    • 1970-01-01
    • 2018-04-16
    相关资源
    最近更新 更多