如何使用 ValidityAuditStrategy 批量插入以审核 table 以进行收集

How can I batch inserts to audit table for collection using ValidityAuditStrategy

我正在使用 Hibernate envers 进行审计,我的大多数表都可以很好地执行批量插入。但是,在我的一个实体上,我有一个经过审计的集合,它似乎不想批处理。

我的实体:

@Entity
@DynamicUpdate
@Indexed(index = "aj")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ElementGroup {
  ...      
@ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.DETACH, CascadeType.MERGE })
    @BatchSize(size = 30)
    @OrderBy("id ASC")
    @JoinTable(
            name = "element_groups",
            joinColumns = @JoinColumn(name = "group_id"),
            inverseJoinColumns = @JoinColumn(name = "member_id")
    )
    @Audited
    protected List<Element> members = new LinkedList<Element>();

(不确定这是否重要,我使用的是 postgresql)。在日志中,我在一个循环中看到了 1000 条这样的语句

DEBUG 2021-11-07 15:28:56,673 [applicationInterfcePublishTaskExecuter-4::o.h.SQL.logStatement] [user:system] 
insert 
into
    nst_netobj_groups_aud
    (revtype, revend, rev, group_id, member_id) 
values
    (?, ?, ?, ?, ?)
DEBUG 2021-11-07 15:28:56,677 [applicationInterfcePublishTaskExecuter-4::o.h.SQL.logStatement] [user:system] 
    select
        nst_netobj0_.rev as rev1_137_,
        nst_netobj0_.group_id as group_id2_137_,
        nst_netobj0_.member_id as member_i3_137_,
        nst_netobj0_.revtype as revtype4_137_,
        nst_netobj0_.revend as revend5_137_ 
    from
        nst_netobj_groups_aud nst_netobj0_ 
    where
        nst_netobj0_.group_id=? 
        and nst_netobj0_.member_id=? 
        and (
            nst_netobj0_.revend is null
        ) for update
            of nst_netobj0_

做一些调试,我了解到 select for update 语句导致先前插入的刷新,不允许它们进行批处理。 这行似乎是原因:

        final List<Object> l = qb.toQuery( session ).setLockOptions( LockOptions.UPGRADE ).list();

hibernate-envers-5.4.27.Final-sources.jar!/org/hibernate/envers/strategy/internal/ValidityAuditStrategy.java:328

我看到将刷新模式设置为 Manual/Commit 似乎没有帮助。 有什么建议吗?

完整堆栈跟踪:

    logStatement:125, SqlStatementLogger (org.hibernate.engine.jdbc.spi)
prepareStatement:170, StatementPreparerImpl$StatementPreparationTemplate (org.hibernate.engine.jdbc.internal)
prepareQueryStatement:151, StatementPreparerImpl (org.hibernate.engine.jdbc.internal)
prepareQueryStatement:2104, Loader (org.hibernate.loader)
executeQueryStatement:2041, Loader (org.hibernate.loader)
executeQueryStatement:2019, Loader (org.hibernate.loader)
doQuery:948, Loader (org.hibernate.loader)
doQueryAndInitializeNonLazyCollections:349, Loader (org.hibernate.loader)
doList:2850, Loader (org.hibernate.loader)
doList:2832, Loader (org.hibernate.loader)
listIgnoreQueryCache:2664, Loader (org.hibernate.loader)
list:2659, Loader (org.hibernate.loader)
list:506, QueryLoader (org.hibernate.loader.hql)
list:400, QueryTranslatorImpl (org.hibernate.hql.internal.ast)
performList:219, HQLQueryPlan (org.hibernate.engine.query.spi)
list:1414, SessionImpl (org.hibernate.internal)
doList:1625, AbstractProducedQuery (org.hibernate.query.internal)
list:1593, AbstractProducedQuery (org.hibernate.query.internal)
performCollectionChange:328, ValidityAuditStrategy (org.hibernate.envers.strategy.internal)
performCollectionChange:76, AuditStrategy (org.hibernate.envers.strategy)
perform:87, PersistentCollectionChangeWorkUnit (org.hibernate.envers.internal.synchronization.work)
executeInSession:125, AuditProcess (org.hibernate.envers.internal.synchronization)
doBeforeTransactionCompletion:164, AuditProcess (org.hibernate.envers.internal.synchronization)
doBeforeTransactionCompletion:47, AuditProcessManager (org.hibernate.envers.internal.synchronization)
beforeTransactionCompletion:954, ActionQueue$BeforeTransactionCompletionProcessQueue (org.hibernate.engine.spi)
beforeTransactionCompletion:525, ActionQueue (org.hibernate.engine.spi)
beforeTransactionCompletion:2381, SessionImpl (org.hibernate.internal)
beforeTransactionCompletion:447, JdbcCoordinatorImpl (org.hibernate.engine.jdbc.internal)
beforeCompletionCallback:183, JdbcResourceLocalTransactionCoordinatorImpl (org.hibernate.resource.transaction.backend.jdbc.internal)
access0:40, JdbcResourceLocalTransactionCoordinatorImpl (org.hibernate.resource.transaction.backend.jdbc.internal)
commit:281, JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl (org.hibernate.resource.transaction.backend.jdbc.internal)
commit:101, TransactionImpl (org.hibernate.engine.transaction.internal)
doCommit:562, JpaTransactionManager (org.springframework.orm.jpa)
processCommit:743, AbstractPlatformTransactionManager (org.springframework.transaction.support)
commit:711, AbstractPlatformTransactionManager (org.springframework.transaction.support)
execute:152, TransactionTemplate (org.springframework.transaction.support)
lambda$publishApplicationInterfaceAsync[=14=]:298, ApplicationInterfaceService (com.tufin.secureapp.service.interfaces)
run:-1, 16579879 (com.tufin.secureapp.service.interfaces.ApplicationInterfaceService$$Lambda9)
runWorker:1149, ThreadPoolExecutor (java.util.concurrent)
run:624, ThreadPoolExecutor$Worker (java.util.concurrent)
run:748, Thread (java.lang)

我检查了一下,这是我发现的:

  • Chris 在我担任 Hibernate 开发人员期间一直在进行大部分 Envers 修复,他写道 告诉我目前没有解决方法
  • 针对此问题创建了 HHH-14664 问题,但没有人提供解决方案。

因此,在有人修复 [HHH-14664] 之前,唯一的选择是提供 CustomValidityAuditStrategy 来扩展 ValidityAuditStrategy 并修复问题。