给定一个由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
,但这不是必需的。
希望您理解。