Hibernate Envers - 在 ValidityAuditStrategy 中使用 allow_identifier_reuse=true 支持 JDBC 批处理

Posted

技术标签:

【中文标题】Hibernate Envers - 在 ValidityAuditStrategy 中使用 allow_identifier_reuse=true 支持 JDBC 批处理【英文标题】:Hibernate Envers - Support for JDBC batching in ValidityAuditStrategy with allow_identifier_reuse=true 【发布时间】:2018-12-21 15:27:19 【问题描述】:

使用 Hibernate + Envers(版本 5.2.17.Final),我尝试保留大约 250000 个 JPA 实体并使用 Envers ValidityAuditStrategy 审核初始插入。我正在使用 JDBC 批处理来提高性能。我看到两者都发生了批处理

插入基表(即INSERT INTO dbo.EXAMPLE_TABLE) 插入审计表(即INSERT INTO dbo.EXAMPLE_TABLE_AUD

但不适用于用于更新任何先前审计行的最终修订的查询,我相信在设置 allow_identifier_reuse=true 时启用(这对于我的用例是强制性的)。这些更新查询之一的示例:

update
    dbo.example_table_aud
set
    revend=? 
where
    id=? 
    and rev<> ? 
    and revend is null

实体代码:

@Entity
@Audited
@Table(schema = "dbo", name = "EXAMPLE_TABLE")
public class ExampleEntity 

    @Id
    @Column(name = "ID", nullable = false)
    private long id;

    @Column(name = "NAME", nullable = false)
    private String name;

    @Version
    @Column(name = "VERSION", nullable = false)
    private int version;

    public long getId() 
        return id;
    

    public void setId(long id) 
        this.id = id;
    

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

    public int getVersion() 
        return version;
    

    public void setVersion(int version) 
        this.version = version;
    

休眠/环境配置:

  org.hibernate.envers:
    audit_table_suffix: _AUD
    revision_field_name: REV
    revision_type_field_name: REVTYPE
    default_schema: dbo
    audit_strategy: org.hibernate.envers.strategy.ValidityAuditStrategy
    do_not_audit_optimistic_locking_field: false
    store_data_at_delete: true
    allow_identifier_reuse: true
  hibernate:
    dialect: org.hibernate.dialect.SQLServer2012Dialect
    format_sql: true
    jdbc.batch_size: 100
    jdbc.batch_versioned_data: true
    order_inserts: true
    order_updates: true

是否有一种解决方法可以为查询启用 JDBC 批处理以更新任何先前行的最终修订?

【问题讨论】:

【参考方案1】:

您提到的更新有几个原因:

    标识符重用(实际上只对 REV_TYPE = 0 或 RevisionType.ADD 行很重要)。 REV_TYPE != 0(又名RevisionType.MODRevisionType.DEL 行)。

目前没有真正的解决方法可以批量处理这些语句,主要是因为这些更新的工作原理。现有的策略期望这些谓词影响表中的单个行,因此也会将其作为其完整性检查的一部分进行检查,否则我们会强制事务失败。

我认为找到一种方法来做到这一点以便批量插入/更新可以工作会很棒,但我们首先必须找到一种方法来实现这些更新并在只有一行的情况下保持相同的完整性检查会受到这种变化的影响,而不是受到延迟的影响。

说了这么多;所有这些逻辑都在ValidityAuditStrategy 中处理,这是用户的可插拔选项,因此您可能会找到一个可行的解决方案,您可以与我们分享。

无论哪种情况,我都建议向我们提出 JIRA 增强问题,我们可以更详细地讨论(如果可能的话)如何最好地处理可能支持的批量插入/更新,并且更高效。

【讨论】:

以上是关于Hibernate Envers - 在 ValidityAuditStrategy 中使用 allow_identifier_reuse=true 支持 JDBC 批处理的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate Envers @NotAudited 注解

在 Spring Hibernate java 项目中使用“Envers”审计表

Hibernate Envers

Hibernate 4.3.11 - Envers 因 ZonedDateTime 字段而失败

Hibernate Envers - 获取已更改的字段

审计没有 Hibernate Envers 的 java 实体