Hibernate 休眠环境:修订的外键

Hibernate 休眠环境:修订的外键,hibernate,hibernate-envers,Hibernate,Hibernate Envers,是否可以向实体的修订版添加外键 例如,如果我有实体个人: @Entity @Audited public class Person { @Id @Column private Integer idPerson; @Column private String favoriteHobby; } 我想指出一个人的修改。比如说,我创建了一本年鉴,我希望它包含那个人目前最喜欢的爱好,但是如果这个人以后会更新他/她最喜欢的爱好,我希望年鉴包含以前的爱好 在SQL中,

是否可以向实体的修订版添加外键

例如,如果我有实体
个人

@Entity
@Audited
public class Person {
    @Id
    @Column
    private Integer idPerson;
    @Column
    private String favoriteHobby;
}
我想指出一个人的修改。比如说,我创建了一本年鉴,我希望它包含那个人目前最喜欢的爱好,但是如果这个人以后会更新他/她最喜欢的爱好,我希望年鉴包含以前的爱好

在SQL中,这可以通过创建一个包含列
idPerson
idRevision
idearbook
的表来实现


但我不确定是否以及如何将其转化为一个实体,查询它,创建我的年鉴。。。无需编写自定义查询或复制我的个人实体。

要首先从评论中回答您的问题,请选择“是”

如果将两个实体都标记为
@Audited
,则对任一实体所做的任何更改都将导致在该特定实体的审核架构中创建新的审核行

AuditReader
API模仿了许多旧的Hibernate标准API。基本上,您可以基于已审核的实体类型构建任何查询,并应用大量条件来过滤结果

我想在此提出一个警告

让我们假设在交易中,我们创建了一个
,并将其放入
年鉴

final Session session = openSession();
try {
   session.getTransaction().begin();

   final Person person = new Person();
   person.setName( "John Doe" );
   person.setHobby( "Plays Guitar" );
   session.save( person );

   final YearBook yearBook = new YearBook();
   yearBook.setYear( 2018 );
   yearBook.getPeople().add( person );
   session.save( yearBook );

   session.getTransaction().commit();
}
catch( Exception ex ) {
   if ( session.getTransaction().isActive() ) {
     session.getTransaction().rollback();
   }
   throw ex;
}
finally {
  session.close();
}
这意味着在审计模式中,将为这两种实体类型创建一个新的审计行,并且这些行将与相同的修订号相关联。为了简单起见,假设这是修订号1

在未来的交易中,您将修改此John Doe的
人员

在这一点上:

  • 年鉴
    作为单一修订版,修订版#1
  • Person
    forjohndoe有两个修订版,修订版#1和#2
这里需要注意的是,对于
年鉴
1修订版的查询将永远不会返回关于
个人
的任何信息。在几乎所有情况下,这绝对是理想的结果;然而,在某些特殊情况下,用户也希望
年鉴
触发修订

如果希望集合所有者在修改不影响集合本身状态的元素属性时也生成修订,则需要在容器上放置一个虚拟属性,并将其作为事务的一部分进行修改,以便两者都得到审核

这就是说,你将如何着手获得年鉴的修订版?使用
AuditReader
API,这非常简单:

final AuditReader reader = AuditReaderFactory.get( session );

// Get the revisions in ascending order from smallest to highest rev #
List<Number> revisions = reader
  .forRevisionsOfEntity( YearBook.class, false )
  .getResultList();

查看文档,了解使用Envers提供的
AuditReader
界面创建查询的所有其他方法。

首先从评论中回答您的问题,是的

如果将两个实体都标记为
@Audited
,则对任一实体所做的任何更改都将导致在该特定实体的审核架构中创建新的审核行

AuditReader
API模仿了许多旧的Hibernate标准API。基本上,您可以基于已审核的实体类型构建任何查询,并应用大量条件来过滤结果

我想在此提出一个警告

让我们假设在交易中,我们创建了一个
,并将其放入
年鉴

final Session session = openSession();
try {
   session.getTransaction().begin();

   final Person person = new Person();
   person.setName( "John Doe" );
   person.setHobby( "Plays Guitar" );
   session.save( person );

   final YearBook yearBook = new YearBook();
   yearBook.setYear( 2018 );
   yearBook.getPeople().add( person );
   session.save( yearBook );

   session.getTransaction().commit();
}
catch( Exception ex ) {
   if ( session.getTransaction().isActive() ) {
     session.getTransaction().rollback();
   }
   throw ex;
}
finally {
  session.close();
}
这意味着在审计模式中,将为这两种实体类型创建一个新的审计行,并且这些行将与相同的修订号相关联。为了简单起见,假设这是修订号1

在未来的交易中,您将修改此John Doe的
人员

在这一点上:

  • 年鉴
    作为单一修订版,修订版#1
  • Person
    forjohndoe有两个修订版,修订版#1和#2
这里需要注意的是,对于
年鉴
1修订版的查询将永远不会返回关于
个人
的任何信息。在几乎所有情况下,这绝对是理想的结果;然而,在某些特殊情况下,用户也希望
年鉴
触发修订

如果希望集合所有者在修改不影响集合本身状态的元素属性时也生成修订,则需要在容器上放置一个虚拟属性,并将其作为事务的一部分进行修改,以便两者都得到审核

这就是说,你将如何着手获得年鉴的修订版?使用
AuditReader
API,这非常简单:

final AuditReader reader = AuditReaderFactory.get( session );

// Get the revisions in ascending order from smallest to highest rev #
List<Number> revisions = reader
  .forRevisionsOfEntity( YearBook.class, false )
  .getResultList();

查看文档,了解使用Envers提供的
AuditReader
界面创建查询的所有其他方法。

您的数据模型中是否认为
年鉴
是不可变的?如果是这样,如果你能确定你要找的特定年鉴,你就可以遍历到所有相关的
,并获得你要找的信息。@Naros你的意思是如果我要对
年鉴
进行审计,我将能够得到一本存档的年鉴,并遍历到当时链接到该年鉴的所有人的当前状态?在您的数据模型中,
年鉴
是否视为不可变?如果是这样,如果你能确定你要找的特定年鉴,你就可以遍历到所有相关的
,并获得你要找的信息。@Naros你的意思是如果我要对
年鉴
进行审计,我将能够得到一本存档的年鉴,并遍历到当时与年鉴相关的所有人