Hibernate Enver : @AuditJoinTable rows missing



给定一个由Envers审核的实体,该实体包含一个集合。

实体

  @Audited
    public class A{
     @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    ....
    @OneToMany
    @JoinColumn(name = "a_id")
    @AuditJoinTable(name = "A_B_AUDIT"
            ,inverseJoinColumns = @JoinColumn(name = "a"))
    private List<B> bs;
    ....
}

实体B

@Audited
public class B{
 @Id
 private int id;
 ....
 @Column(name = "a_id")
 private int aId;
 @ManyToOne
 @JoinColumn(name = "a_id", insertable = false, updatable = false)
 private A a;
}

根据他们的文档Envers将审核信息存储在这些审核之间(A_B_AUDIT)中的添加和删除。但不幸的是,这不起作用,桌子内部的行丢失了。

当我运行项目时,创建了以下表格:

a_audit

b_audit

a_b_audit

我已经分开控制器来持续一个对象和b对象。当我尝试使用援助和A保存B时,Audit_table( a_b_audit )不会更新,但是 b_audit 随着更新的修订版已更新。

有人可以让我知道我在这里缺少什么。

谢谢!

Hibernate Enver版本:5.1.4.final

如评论中所述,您的问题是您在单独的交易中执行这两个实体的持久性,但是您没有建立适当的关联Hibernate的第一级缓存。无意间,您还导致Envers无法正确审核您的实体,因为您没有给予所有适当的状态。

为了使此用例与Envers一起使用,您需要修改如何处理实体B的持久性,因为这似乎是唯一关于与之的关系的 neve 实体A

在实体B的持久性期间,您可能应该这样做:

if ( b.getAId() != null ) {
  A a = entityManager.find( A.class, b.getAId() );
  a.getBs().add( b );
  a = entityManager.merge( a );
  b.setA( a );
  entityManager.persist( b );
}

这意味着在实体B的持久性期间,您应该像您预期的那样在审核上添加一个审核行,并且Hibernate的第一级缓存中的状态将包含两个实体之间的所有适当参考。

如果我们将Envers放在一边,并专注于正常的JPA提供商的使用情况,则在您坚持B之后,您应该能够执行此操作,并且它将起作用:

final A theA = b.getA();
assertNotNull( theA );
assertTrue( !theA.getBs().isEmpty() );
assertTrue( theA.getBs().contains( b ) );

显然,如果您不设置关联,这些断言(应该通过)就不会。他们唯一会通过的时间是您请求实体B,但这不是必需的。

希望您理解。

相关内容

  • 没有找到相关文章

最新更新