[JIRA] (HHH-16668) ConcurrentModificationException when using a criteria with window functions in hibernate 6
by Dāvis Sparinskis (JIRA)
Dāvis Sparinskis ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... ) *created* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiN2U4M2M0ZWU4... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-16668?atlOrigin=eyJpIjoiN2U4M2... ) HHH-16668 ( https://hibernate.atlassian.net/browse/HHH-16668?atlOrigin=eyJpIjoiN2U4M2... ) ConcurrentModificationException when using a criteria with window functions in hibernate 6 ( https://hibernate.atlassian.net/browse/HHH-16668?atlOrigin=eyJpIjoiN2U4M2... )
Issue Type: Bug Affects Versions: 6.2.1 Assignee: Unassigned Components: query-criteria Created: 22/May/2023 07:27 AM Priority: Major Reporter: Dāvis Sparinskis ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... )
When using hibernate reactive with hibernate 6, I’m getting a org.hibernate.HibernateException: java.util.ConcurrentModificationException when trying to use window functions with the HibernateCriteriaBuilder.
Example
final var cb = sessionFactory.getCriteriaBuilder();
final var query = cb.createQuery( Long.class);
final var root = query.from(Entity.class);
final var rowNumber = cb.rowNumber(
cb.createWindow()
.partitionBy(root.get( "chargePoint" ))
.orderBy(cb.desc(root.get( "startTime" )))
);
query.select(rowNumber.alias( "rowNumber" ));
session.createQuery(query).getResultList();
Expected result
A query is generated that retrieves a list of the row numbers of the entities.
Actual result
org.hibernate.HibernateException: java.util.ConcurrentModificationException
at org.hibernate.reactive.session.impl.ReactiveExceptionConverter.convert(ReactiveExceptionConverter.java:28)
at org.hibernate.reactive.session.impl.ReactiveSessionImpl.createReactiveQuery(ReactiveSessionImpl.java:368)
at org.hibernate.reactive.mutiny.impl.MutinySessionImpl.createQuery(MutinySessionImpl.java:140)
at de.porsche.ho.chargepointservice.database.repository.ChargeTransactionRepository.lambda$findUserTransactions$0(ChargeTransactionRepository.java:99)
at io.smallrye.context.impl.wrappers.SlowContextualFunction.apply(SlowContextualFunction.java:21)
at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni$UniOnItemTransformToUniProcessor.performInnerSubscription(UniOnItemTransformToUni.java:68)
at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni$UniOnItemTransformToUniProcessor.onItem(UniOnItemTransformToUni.java:57)
at io.smallrye.mutiny.operators.uni.builders.UniCreateFromKnownItem$KnownItemSubscription.forward(UniCreateFromKnownItem.java:38)
at io.smallrye.mutiny.operators.uni.builders.UniCreateFromKnownItem.subscribe(UniCreateFromKnownItem.java:23)
at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni.subscribe(UniOnItemTransformToUni.java:25)
at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
at io.smallrye.mutiny.operators.uni.UniOnItemTransform.subscribe(UniOnItemTransform.java:22)
at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
at io.smallrye.mutiny.operators.uni.UniOnItemConsume.subscribe(UniOnItemConsume.java:30)
at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni.subscribe(UniOnItemTransformToUni.java:25)
at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni.subscribe(UniOnItemTransformToUni.java:25)
at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
at io.smallrye.mutiny.operators.uni.UniOnFailureFlatMap.subscribe(UniOnFailureFlatMap.java:31)
at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
at io.smallrye.mutiny.operators.uni.UniOnCancellationCall.subscribe(UniOnCancellationCall.java:27)
at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni.subscribe(UniOnItemTransformToUni.java:25)
at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni.subscribe(UniOnItemTransformToUni.java:25)
at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni$UniOnItemTransformToUniProcessor.performInnerSubscription(UniOnItemTransformToUni.java:81)
at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni$UniOnItemTransformToUniProcessor.onItem(UniOnItemTransformToUni.java:57)
at io.smallrye.mutiny.operators.uni.builders.UniCreateFromCompletionStage$CompletionStageUniSubscription.forwardResult(UniCreateFromCompletionStage.java:63)
at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863)
at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2147)
at io.vertx.core.Future.lambda$toCompletionStage$3(Future.java:384)
at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
at io.vertx.core.impl.future.FutureImpl$ListenerArray.onSuccess(FutureImpl.java:262)
at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)
at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211)
at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23)
at io.vertx.core.impl.future.PromiseImpl.onSuccess(PromiseImpl.java:49)
at io.vertx.core.impl.future.PromiseImpl.handle(PromiseImpl.java:41)
at io.vertx.sqlclient.impl.TransactionImpl.lambda$wrap$0(TransactionImpl.java:72)
at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess$0(FutureBase.java:54)
at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
at org.hibernate.query.sqm.tree.expression.SqmWindow.copy(SqmWindow.java:173)
at org.hibernate.query.sqm.tree.expression.SqmOver.copy(SqmOver.java:73)
at org.hibernate.query.sqm.tree.expression.SqmOver.copy(SqmOver.java:23)
at org.hibernate.query.sqm.tree.select.SqmSelection.copy(SqmSelection.java:47)
at org.hibernate.query.sqm.tree.select.SqmSelectClause.copy(SqmSelectClause.java:52)
at org.hibernate.query.sqm.tree.select.SqmQuerySpec.copy(SqmQuerySpec.java:101)
at org.hibernate.query.sqm.tree.select.SqmQuerySpec.copy(SqmQuerySpec.java:53)
at org.hibernate.query.sqm.tree.select.SqmSelectStatement.copy(SqmSelectStatement.java:131)
at org.hibernate.query.sqm.tree.select.SqmSelectStatement.copy(SqmSelectStatement.java:42)
at org.hibernate.query.sqm.internal.QuerySqmImpl.<init>(QuerySqmImpl.java:228)
at org.hibernate.reactive.query.sqm.iternal.ReactiveQuerySqmImpl.<init>(ReactiveQuerySqmImpl.java:112)
at org.hibernate.reactive.session.impl.ReactiveSessionImpl.createCriteriaQuery(ReactiveSessionImpl.java:373)
at org.hibernate.reactive.session.impl.ReactiveSessionImpl.createReactiveQuery(ReactiveSessionImpl.java:362)
... 52 more
From quick debugging I’ve found these lines to be very suspicious:
hibernate-core-6.2.1.Final-sources.jar!/org/hibernate/query/sqm/tree/expression/SqmWindow.java:174
hibernate-core-6.2.1.Final-sources.jar!/org/hibernate/query/sqm/tree/expression/SqmWindow.java:178
In this fragment from hibernate-core-6.2.1.Final-sources.jar!/org/hibernate/query/sqm/tree/expression/SqmWindow.java it looks like when copying from partitions and orderList it is added to the original lists instead of the newly created partitionsCopy and orderListCopy which causes the ConcurrentModificationException.
final List<SqmExpression<?>> partitionsCopy = new ArrayList<>( this.partitions.size() );
for ( SqmExpression<?> partition : this.partitions ) {
partitions.add( partition.copy( context ) );
}
final List<SqmSortSpecification> orderListCopy = new ArrayList<>( this.orderList.size() );
for ( SqmSortSpecification sortSpecification : this.orderList ) {
orderList.add( sortSpecification.copy( context ) );
}
( https://hibernate.atlassian.net/browse/HHH-16668#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-16668#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100225- sha1:bbd69a1 )