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=Em...
) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100225- sha1:bbd69a1 )