【问题标题】:Retrieve Revisions of Mapping Tables - Hibernate Envers检索映射表的修订 - Hibernate Envers
【发布时间】:2017-10-09 11:33:03
【问题描述】:

我正在使用带有 Envers 的 Hibernate,4.3.6 FINAL。我已经使用注释设置了审计,并且当我在应用程序中保存信息时,我的所有审计表都已创建并正确填充。我的一个审计实体有一个到其他实体的映射表,配置为 @ManyToMany。

雇主 -> 职务

雇主可以有 0 到 n 个与之关联的指定实体。映射表是标准的,只有两列,一个是 Employers 表的外键,一个是 Designations 表的外键。 Envers 为这个映射表创建了一个审计表,并且记录被适当地记录,当编辑 Employer 时,插入或删除输入的 REV 与 Employer 相同。

我现在要做的是从数据库中检索审计信息,以便将其呈现以用于报告目的。正在检索我的雇主的修订列表,并且给定修订的雇主状态是准确的。我无法弄清楚的是如何检索映射表的审计。我没有这些配对的实际实体。它们使用 javax.persistence.JoinTable 注释放在一起。因此,我的 REVCHANGES 表中没有实体记录(我将 org.hibernate.envers.track_entities_changed_in_revision 设置为 true)。查看数据库,有我的 EmployerDesignations 映射表和相应的 EmployerDesignations_AUD 审计表的记录,但我不知道如何检索这些审计记录,也不知道它们何时已针对给定的修订进行了更改。

如何检索映射表的审计历史记录?

雇主类别:

@Entity
@DynamicInsert
@DynamicUpdate
@SelectBeforeUpdate
@Table(name="EMPLOYERS")
@Audited
public class Employer implements Serializable {

    //All other fields omitted for brevity
    ...

    private List<Designations> designations;
    @ManyToMany
    @JoinTable(name = "EMPLOYERDESIGNATIONS", 
        joinColumns =           { @JoinColumn(name = "FK_EMPLOYER", nullable = false) },
        inverseJoinColumns =    { @JoinColumn(name = "FK_DESIGNATION", nullable = false) })
    public List<Designations> getDesignations() {
        return designations;
    }
    public void setDesignations(List<Designations> designations) {
        this.designations= designations;
    }
}

指定类别:

@Entity
@DynamicInsert
@DynamicUpdate
@SelectBeforeUpdate
@Table(name="DESIGNATIONS")
@Audited
public class Designation implements Serializable {

    //All other fields omitted for brevity
    ...

    private List<Employer> employers;
    @ManyToMany
    @JoinTable(name = "EMPLOYERDESIGNATIONS", 
        joinColumns =           { @JoinColumn(name = "FK_DESIGNATION", nullable = false) },
        inverseJoinColumns =    { @JoinColumn(name = "FK_EMPLOYER", nullable = false) })
    public List<Employer> getEmployers() {
        return employers;
    }
    public void setEmployers(List<Employer> employers) {
        this.employers= employers;
    }
}

审计数据检索测试代码:

List<Number> revisions = reader.getRevisions(Employer.class, employerId);
System.out.println(revisions);
for (Number revisionNum : revisions) {
    Employer employer = reader.find(Employer.class, employerId, revisionNum);
    System.out.println(employer);
}

【问题讨论】:

    标签: java hibernate-envers


    【解决方案1】:

    您需要做的就是检索Employer 实例,然后简单地访问关联的getter,并且在实体被审计时关联的任何状态都将自动可用。

    如果我们假设 Envers 环境中的第一个操作是您创建一个 Employer 并通过您的联接将其与两个 Designation 实体相关联,那么当您获取修订版 1 的 Employer 实例时,该集合将具有两个元素。

    稍后在事务 2 中,您修改 Employer 并删除一个 Designation 并向实体添加一个新的 Designation,然后当您在修订版 2 中获取 Employer 时,它仍将包含两个 @ 987654331@ 个实体实例,但这些实例将是第一个修订版中保留的实例以及您在第二个修订版中添加的第二个实例。

    【讨论】:

    • 有什么特别需要做的吗?即使我直接使用吸气剂,恐怕我的指定列表也是空的。断点我的代码,我看到指定列表实际上是 org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.ListProxy 的一个实例。
    • 更正它的代理,该代理将在首次以某种有意义的方式访问列表时加载,例如获取它的大小或元素。
    • 我一定是在某种程度上做错了什么。我已经尝试使用 size() 初始化列表,如您所述和this question 中所述,但结果列表为空。我知道我正在测试的给定修订号有审核数据,但似乎根本没有填充指定列表。
    • 从我所看到的代码方面来看,这应该可以工作。请在gist.github.com/Naros/96537efe7e2a3e5cabaebef623f2f77d 上查看我的要点,以获取我模拟您的实体并且效果很好的示例。了解您可能面临的问题是 4.3 中出现的问题,如果这是真的,您需要更新到 5.2。
    • 谢谢。我会用 4.3 和 5.2 测试一下,看看这两个版本之间是否有任何区别。
    猜你喜欢
    • 2012-10-25
    • 1970-01-01
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 2013-05-24
    • 1970-01-01
    • 1970-01-01
    • 2011-07-03
    相关资源
    最近更新 更多