java - Hibernate Enver 不审核软删除中使用的字段?

标签 java hibernate hibernate-envers

我正在使用 hibernate.envers 设置:

properties.put("org.hibernate.envers.audit_table_suffix", "_HISTORY");
properties.put("org.hibernate.envers.store_data_at_delete", "true");

主表如下:

@Entity
@Table(name = "person")
@SQLDelete(sql = "UPDATE person SET deleted = NOW() WHERE id = ?", check = ResultCheckStyle.COUNT)
@Where(clause = "deleted is NULL")
@Audited
public class Person {
  @Id
  private UUID id;

  private OffsetDateTime deleted;

  //omit other fields
}

当删除事件发生时,Person_HISTORY表将存储除deleted字段之外的Person的所有字段。 (Person_HISTORY 表中的deleted 字段为空)

知道如何在删除事件发生时将deleted字段存储到Person_HISTORY中吗?

最佳答案

简单来说,对deleted的修改不包含在PostDeleteEvent中。

Hibernate 在实体删除工作流程开始时构建一次包含在 PostDeleteEvent 中的状态。对于传统用途,这是有意义的,因为正在执行的语句是DELETE,因此该行不会被修改。

这里的难题是 @SQLDelete 仅用自定义版本替换实体持久化器使用的生成的 DELETE 语句。一般来说,您提供的 SQL 可以是任何内容,只要它是语法上有效的 DML 即可。

Hibernate 不知道的是,本例中的替换 SQL 是 UPDATE。因此,在持久化程序执行删除 SQL 语句之后,不会发生持久化程序快照状态的重新同步,并且事件的状态不会发生更改,并且当 post-delete 回调触发时,它们仍然会被提供实体删除工作流程开始时的状态。

话虽如此,Envers 确实在审核表中记录了 REVTYPE=2(又名 DEL)。因此,如果您需要删除的时间戳,您仍然可以从 Envers REVINFO 表中获取它。

更新

这里的另一个想法是使用两列而不是单列。不要使用时间戳作为软删除指示器,而是使用位标志

@Entity
@Audited
@SQLDelete("UPDATE person SET deleted = true WHERE id = ?")
@Where(clause = "deleted is NULL or deleted != true")
public class Person {
  @NotAudited
  private boolean deleted;
  private OffsetDateTime deleteTime;
  @PreRemove
  public void onPreRemove() {
    this.deleteTime = ...;
  }
}

这里我使用 @PreRemove 来设置删除时间值,然后将该值在 PostDeleteEvent 中传递给 Envers,并让 Hibernate 管理位字段。由于事件状态中从未提供 deleted 字段,因此我将其标记为 @NotAudited 以将其从审核架构中排除。

关于java - Hibernate Enver 不审核软删除中使用的字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50245463/

相关文章:

java - 当存储库返回类型为 List<Post> 时,Spring JPA 查询返回 List<PageImpl>

java非阻塞缓存实现

java - PDFBOX:将 pdf 转换为文本或 html,包括 pdf 中的图像

java - Spring hibernate @param 将映射到什么

java - 在实体类中创建其他公共(public)方法

java - 当一个对象的使用只在一个地方出现同步块(synchronized block)时会发生什么?

java - 将 SXSSFWorkbook 保存到 blob 的最佳方法?

java - 如何摆脱 "HHH90000003: Use of DOM4J entity-mode is considered deprecated"

mysql - 恩弗斯 : auto_increment (not PK) column not being audited

java - Envers Hibernate 记录表的创建/更改