如何阅读与标记为 NOT_AUDITED 的关联相关的修改

How to read modifications related to association marked with NOT_AUDITED

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

@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 table。但它会生成一个 JOB_COMMENT_AUD table.

如何从 AuditReader 中获取相应的评论实体?我只能使用 AuditReader 读取作业实体。或者换句话说:我需要使用 AuditReader.

访问 JOB_COMMENT_AUD 条目

一定可以通过 AuditReader 获取相应的 Comment 实体。为什么 hibernate 还要审核自动生成的 JOB_COMMENT_AUD table 中的关系?

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

这个注解将使 Envers 生成一个 join-table,维护被审计实体 Job 和 [=14] 的 ORM 数据 table 之间的外键到主键的关系=] 实体。

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

的集合

来自AuditReader,只能查询Job类型。这是因为您只标记了要审核的 Job 类型,而不是 Comment 类型。但这并不意味着当您获得 Job.

的审核实例时,您无法获取关联的 Comment
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 table 和基础 Comment table 为您的实体加载实体数据。

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

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 会为您无缝处理。