hibernate - HIbernate Envers:修改的外键
问题描述
是否可以将外键添加到实体的修订中?
例如,如果我有实体Person
:
@Entity
@Audited
public class Person {
@Id
@Column
private Integer idPerson;
@Column
private String favoriteHobby;
}
我想指出一个人的修订。假设我创建了一本年鉴,我希望它包含那个人目前最喜欢的爱好,但是如果这个人之后会更新他/她最喜欢的爱好,我希望年鉴包含旧的爱好。
在 SQL 中,这将通过创建一个包含 和 列的表来idPerson
完成。idRevision
idYearBook
但是我不确定是否以及如何将其转换为实体,查询它,创建我的年鉴......而不编写自定义查询或复制我的个人实体。
解决方案
首先从评论中回答您的问题,是的。
如果您将两个实体都标记为@Audited
,那么您对任一实体所做的任何更改都将导致在该特定实体的审计架构中创建一个新的审计行。
该AuditReader
API 模仿了许多旧的遗留 Hibernate Criteria API。您基本上可以基于已审核的实体类型构建任何查询,并应用大量条件来过滤结果。
这里有一个警告我想提一下。
让我们假设在一个事务中,我们创建一个Person
并将它们放在YearBook
:
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。
在未来的事务中,您Person
为此John Doe进行修改:
final Session session = openSession();
try {
session.getTransaction().begin();
final Person person = session.find( Person.class, personId );
person.setHobby( "Video Games" );
session.getTransaction().commit();
}
catch( Exception ex ) {
if ( session.getTransaction().isActive() ) {
session.getTransaction().rollback();
}
throw ex;
}
finally {
session.close();
}
在此刻:
YearBook
作为单个修订版,修订版 # 1。Person
对于John Doe有两个修订版,修订版 # 1和 # 2。
这里需要注意的是,针对YearBook
版本1的查询永远不会返回您Person
在版本2中的任何内容。这绝对是几乎所有情况下的预期结果;但是,在某些特殊情况下,用户YearBook
也希望触发修订。
如果您希望集合所有者在修改不影响集合本身状态的元素属性时也生成修订,您需要在容器上放置一个虚拟属性并将其作为事务的一部分进行修改所以两者都要接受审计。
也就是说,您将如何着手YearBook
进行修订?使用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();
如果您已经知道感兴趣的修订号,则可以使用以下方法获取该实体的确切快照:
final AuditReader reader = AuditReaderFactory.get( session );
final YearBook yearBook = reader.find( YearBook.class, yearBookId, revision );
查看文档,了解使用AuditReader
Envers 提供的界面创建查询的所有其他方法。
推荐阅读
- jmeter - 我无法记录下订单活动并对随机生成的 URL 执行负载测试
- c# - 为什么 dataTable.Rows[0]["columnName"] == null。不工作?
- xamarin.forms - 动态添加删除部分视图 Prism
- java - Hibernate用NULL覆盖列值?
- flutter - Flutter 使用拖动和按钮单击扩展 TextField
- typescript - 在打字稿中使用带有currying的文字时如何防止缩小泛型类型?
- jsf - 表单未在第一次点击时提交
- javascript - 三元运算符未按预期处理后增量
- html - 引导导航从页面退出
- c# - 是否可以忽略部分视图的模型?