如何阅读与标记为NOT_AUDITED

时间:2018-01-30 11:51:09

标签: hibernate hibernate-envers

在我的用例中,有一个Job,这个Job有评论。由于您无法编辑评论,因此我不想审核此实体。 这是代码:

@Audited(withModifiedFlag = true)
@Entity
@Table(name = "JOB")
public class Job {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column(name = "id")
  private Integer id;

  @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
  @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
  @JoinColumn(name = "j_id")
  private List<Comment> comments;
}

@Entity
@Table(name = "COMMENT")
public class Comment {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column(name = "id")
  private Integer id;

  @Column(name = "title")
  private String title;

  @Column(name = "text")
  private String text;
}

现在我希望能够获取与comments相关的所有修改。 当然Hibernate不会生成COMMENT_AUD表。但是它会生成一个JOB_COMMENT_AUD表。

如何从AuditReader获取相应的评论实体?我只能使用AuditReader读取Job实体。或者换句话说:我需要使用AuditReader访问JOB_COMMENT_AUD条目。

不知何故,必须可以使用AuditReader获取相应的Comment实体。为什么hibernate还应该将关系审核到自动生成的JOB_COMMENT_AUD表中?

1 个答案:

答案 0 :(得分:2)

首先了解RelationalTargetAuditMode.NOT_AUDITED的作用非常重要。

此批注将使Envers生成一个连接表,该连接表维护被审计实体JobComment实体的ORM数据表之间主键关系的外键。

换句话说,Envers不会复制Comment实体的审计模式中的任何列,而只会捕获主键,以便在填充审计的Job实例时,它知道如何正确设置Comment s的集合。

AuditReader开始,只能查询Job种类型。这是因为您只标记了要审核的Job类型,而不是Comment类型。但这并不意味着当您获得Comment的审核实例时,您无法获取关联的Job

final AuditReader auditReader = AuditReaderFactory.get( entityManager );

// Get the first revision of Job with id jobId
// This Job has 2 comments, so here we can get them easily.
final Job job = auditReader.find( Job.class, jobId, 1 );
assertEquals( 2, job.getComments().size() );
assertEquals( "Hello World", job.getComments().get( 0 ).getText() );
assertEquals( "Goodbye World", job.getComments().get( 1 ).getText() );

Envers使用代理包装您的Comment集合,以便在您的代码首次尝试访问它时,它会检查该集合是否已初始化。如果没有,它将根据专门的查询填充集合,该查询知道如何获取有关当前Job实体,Job_Comment_AUD表和基本Comment表的修订数据为您的实体加载实体数据。

换句话说,代理初始化会为您触发这样的查询:

SELECT c.* 
  FROM Comment c, 
       Job_Comment_AUD jc 
 WHERE jc.job_id = :jobId
   AND jc.revision = :jobRevision
   AND jc.comment_id = c.id     

美观是您的代码不需要使用Hibernate Session或JPA EntityManager执行任何特定的提取或查询。当您调用job.getComments()集合时,Envers会为您无缝处理。