首页 文章

Hibernate Enver:缺少@AuditJoinTable行

提问于
浏览
0

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

Entity A

@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;
    ....
}

Entity 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;
}

根据他们的documentation Envers存储有关这些AuditJoinTables(A_B_AUDIT)的添加和删除的审计信息 . 但不幸的是,这不起作用,表中的行丢失了 .

当我运行我的项目后,表格被创建:

A_AUDIT

B_AUDIT

A_B_AUDIT

我将控制器分开来保存A对象和B对象 . 当我尝试使用aId和A保存B时,audit_table( A_B_AUDIT )不会更新,但更新版本的 B_AUDIT 会更新 .

有人可以让我知道我在这里失踪了什么 .

谢谢 !!

Hibernate Enver Version :5.1.4 . 最终

1 回答

  • 1

    正如评论中所述,您的问题是您在单独的事务中执行这两个实体的持久性,但是您没有进行正确的关联,因此您正在污染Hibernate的第一级缓存的状态 . 无意中,您还导致Envers无法正确审核您的实体,因为您没有给它所有正确的状态 .

    为了让这个用例与Envers一起使用,你需要修改你如何处理实体的持久性 B ,因为它似乎只知道与实体 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 ) );
    

    显然,如果你不是't setting the associations, these assertions (which should all pass) won' t . 他们唯一通过的时间是你重新查询实体 B ,但这不应该是必要的 .

    希望你明白 .

相关问题