I'm using Hibernate envers for auditing, and most of my tables are performing batch inserts just fine. However, on one of my entities I have an audited collection, which seems like it doesnt want to batch.
MyEntity:
@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>();
(Not sure if this is important, Im using postgresql). In the logs I see 1000s of these statements in a loop
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_
Doing some debugging, I've understood that the select for update statement is causing the flush of the previous insert, not allowing them to batch. This line seems to be the reason:
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
I see that setting flush mode to Manual/Commit doesnt seem to help. Any suggestions?
Full stack trace:
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$1 (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)
access$300: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$0:298, ApplicationInterfaceService (com.tufin.secureapp.service.interfaces)
run:-1, 16579879 (com.tufin.secureapp.service.interfaces.ApplicationInterfaceService$$Lambda$669)
runWorker:1149, ThreadPoolExecutor (java.util.concurrent)
run:624, ThreadPoolExecutor$Worker (java.util.concurrent)
run:748, Thread (java.lang)