Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate环境:@AuditJoinTable行丢失_Java_Hibernate_Hibernate Envers_Nhibernate Envers_Audit Tables - Fatal编程技术网

Java Hibernate环境:@AuditJoinTable行丢失

Java Hibernate环境:@AuditJoinTable行丢失,java,hibernate,hibernate-envers,nhibernate-envers,audit-tables,Java,Hibernate,Hibernate Envers,Nhibernate Envers,Audit Tables,给定一个由Envers审核的实体,该实体包含一个集合 实体A 根据他们的 Envers存储审计信息,以便添加和删除这些AuditJoinTables A_B_audit。但不幸的是,这不起作用,表中的行丢失 当我运行项目时,将创建以下表格: 审计 B_审计 审计 我有单独的控制器来持久化A对象和B对象。当我尝试用aId和A保存B时,audit_表A_B_audit不会更新,但更新了修订版的B_audit会更新 有人能告诉我我错过了什么吗 谢谢 Hibernate Enver版本:5.1.4.Fi

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

实体A

根据他们的 Envers存储审计信息,以便添加和删除这些AuditJoinTables A_B_audit。但不幸的是,这不起作用,表中的行丢失

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

审计

B_审计

审计

我有单独的控制器来持久化A对象和B对象。当我尝试用aId和A保存B时,audit_表A_B_audit不会更新,但更新了修订版的B_audit会更新

有人能告诉我我错过了什么吗

谢谢


Hibernate Enver版本:5.1.4.Final

如评论中所述,您的问题是您在单独的事务中执行这两个实体的持久化,但您没有进行适当的关联,因此您正在污染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 ) );
显然,如果不设置关联,那么这些应该全部通过的断言就不会通过。它们将通过的唯一时间是当您重新查询实体B时,但这不是必需的


希望您能理解。

我已经用master和5.1.4测试了这两个版本,但我无法重现您的问题,因此这一定是您如何在关系双方设置值的非常具体的问题。在持久化之前,您是否可以在创建实体和关联实体的位置包含代码?您好@Naros,我为它们两个都设置了单独的控制器,根据Hibernate的辅助映射,我正在选择关联。听起来好像您在单独的事务中持久化B和A,并且您在它们之间建立的唯一关联是使用标识符A设置BaId。如果这是真的,并且您没有在中明确地将B添加到列表中A然后,您将无法在联接表中放置值。这不是持久性的工作方式。您需要确保将所有必需的属性都持久化在一起,否则最终会出现部分状态,而Envers将无法正确填充审核历史记录。如果这不是您正在做的,那么您需要再次发布实际的代码。您好@Naros,是的,您在持久化数据的方法上是正确的。有一点很清楚,根据我的实现,我不能使用AuditJoinTable,因为Envers不是这样工作的,但是在这种情况下,除了查询每个关联之外,有没有一种方法可以实现审计细节?
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 );
}
final A theA = b.getA();
assertNotNull( theA );
assertTrue( !theA.getBs().isEmpty() );
assertTrue( theA.getBs().contains( b ) );