Skip to content

ClassCastException in ReactiveEmbeddableInitializerImpl when using an EmbeddedId which contains a reference to another entity #47536

@CyrusSA

Description

@CyrusSA

Describe the bug

Given a setup where I have an entity FooEntity which has an EmbeddedId FooId, and FooId contains a reference to BarEntity, then trying to query FooEntity through Panache causes the following ClassCastException:

[ERROR] org.acme.hibernate.orm.panache.ReproTest.test(TransactionalUniAsserter) -- Time elapsed: 0.124 s <<< ERROR!
java.lang.ClassCastException: class org.hibernate.sql.results.graph.entity.internal.EntitySelectFetchInitializer cannot be cast to class org.hibernate.reactive.sql.results.graph.ReactiveInitializer (org.hibernate.sql.results.graph.entity.internal.EntitySelectFetchInitializer and org.hibernate.reactive.sql.results.graph.ReactiveInitializer are in unnamed module of loader io.quarkus.bootstrap.classloading.QuarkusClassLoader @4cc7d00d)
	at org.hibernate.reactive.sql.results.graph.embeddable.internal.ReactiveEmbeddableInitializerImpl.lambda$forEachReactiveSubInitializer$0(ReactiveEmbeddableInitializerImpl.java:75)
	at org.hibernate.reactive.util.impl.CompletionStages.lambda$loop$2(CompletionStages.java:175)
	at org.hibernate.reactive.util.impl.CompletionStages.lambda$loop$7(CompletionStages.java:410)
	at org.hibernate.reactive.util.impl.CompletionStages$ArrayLoop.next(CompletionStages.java:484)
	at org.hibernate.reactive.util.async.impl.AsyncTrampoline.lambda$asyncWhile$1(AsyncTrampoline.java:215)
	at org.hibernate.reactive.util.async.impl.AsyncTrampoline$TrampolineInternal.unroll(AsyncTrampoline.java:121)
	at org.hibernate.reactive.util.async.impl.AsyncTrampoline$TrampolineInternal.trampoline(AsyncTrampoline.java:102)
	at org.hibernate.reactive.util.async.impl.AsyncTrampoline.asyncWhile(AsyncTrampoline.java:197)
	at org.hibernate.reactive.util.async.impl.AsyncTrampoline.asyncWhile(AsyncTrampoline.java:215)
	at org.hibernate.reactive.util.impl.CompletionStages.loop(CompletionStages.java:411)
	at org.hibernate.reactive.util.impl.CompletionStages.loop(CompletionStages.java:382)
	at org.hibernate.reactive.util.impl.CompletionStages.loop(CompletionStages.java:175)
	at org.hibernate.reactive.sql.results.graph.embeddable.internal.ReactiveEmbeddableInitializerImpl.lambda$forEachReactiveSubInitializer$1(ReactiveEmbeddableInitializerImpl.java:74)
	at org.hibernate.reactive.util.impl.CompletionStages.lambda$loop$2(CompletionStages.java:175)
	at org.hibernate.reactive.util.impl.CompletionStages.lambda$loop$7(CompletionStages.java:410)
	at org.hibernate.reactive.util.impl.CompletionStages$ArrayLoop.next(CompletionStages.java:484)
	at org.hibernate.reactive.util.async.impl.AsyncTrampoline.lambda$asyncWhile$1(AsyncTrampoline.java:215)
	at org.hibernate.reactive.util.async.impl.AsyncTrampoline$TrampolineInternal.unroll(AsyncTrampoline.java:121)
	at org.hibernate.reactive.util.async.impl.AsyncTrampoline$TrampolineInternal.trampoline(AsyncTrampoline.java:102)
	at org.hibernate.reactive.util.async.impl.AsyncTrampoline.asyncWhile(AsyncTrampoline.java:197)
	at org.hibernate.reactive.util.async.impl.AsyncTrampoline.asyncWhile(AsyncTrampoline.java:215)
	at org.hibernate.reactive.util.impl.CompletionStages.loop(CompletionStages.java:411)
	at org.hibernate.reactive.util.impl.CompletionStages.loop(CompletionStages.java:382)
	at org.hibernate.reactive.util.impl.CompletionStages.loop(CompletionStages.java:175)
	at org.hibernate.reactive.sql.results.graph.embeddable.internal.ReactiveEmbeddableInitializerImpl.forEachReactiveSubInitializer(ReactiveEmbeddableInitializerImpl.java:74)
	at org.hibernate.reactive.sql.results.graph.ReactiveInitializer.reactiveResolveKey(ReactiveInitializer.java:36)
	at org.hibernate.reactive.sql.results.graph.entity.internal.ReactiveEntityInitializerImpl.initializeId(ReactiveEntityInitializerImpl.java:749)
	at org.hibernate.reactive.sql.results.graph.entity.internal.ReactiveEntityInitializerImpl.reactiveResolveKey(ReactiveEntityInitializerImpl.java:625)
	at org.hibernate.reactive.sql.results.graph.entity.internal.ReactiveEntityInitializerImpl.reactiveResolveKey(ReactiveEntityInitializerImpl.java:605)
	at org.hibernate.reactive.sql.results.graph.entity.internal.ReactiveEntityInitializerImpl.reactiveResolveKey(ReactiveEntityInitializerImpl.java:56)
	at org.hibernate.reactive.sql.results.internal.ReactiveStandardRowReader.resolveKey(ReactiveStandardRowReader.java:383)
	at org.hibernate.reactive.sql.results.internal.ReactiveStandardRowReader.lambda$coordinateInitializers$28(ReactiveStandardRowReader.java:376)
	at org.hibernate.reactive.util.impl.CompletionStages.lambda$loop$7(CompletionStages.java:410)
	at org.hibernate.reactive.util.impl.CompletionStages$ArrayLoop.next(CompletionStages.java:484)
	at org.hibernate.reactive.util.async.impl.AsyncTrampoline.lambda$asyncWhile$1(AsyncTrampoline.java:215)
	at org.hibernate.reactive.util.async.impl.AsyncTrampoline$TrampolineInternal.unroll(AsyncTrampoline.java:121)
	at org.hibernate.reactive.util.async.impl.AsyncTrampoline$TrampolineInternal.trampoline(AsyncTrampoline.java:102)
	at org.hibernate.reactive.util.async.impl.AsyncTrampoline.asyncWhile(AsyncTrampoline.java:197)
	at org.hibernate.reactive.util.async.impl.AsyncTrampoline.asyncWhile(AsyncTrampoline.java:215)
	at org.hibernate.reactive.util.impl.CompletionStages.loop(CompletionStages.java:411)
	at org.hibernate.reactive.util.impl.CompletionStages.loop(CompletionStages.java:382)
	at org.hibernate.reactive.sql.results.internal.ReactiveStandardRowReader.coordinateInitializers(ReactiveStandardRowReader.java:376)
	at org.hibernate.reactive.sql.results.internal.ReactiveStandardRowReader.reactiveReadRow(ReactiveStandardRowReader.java:126)
	at org.hibernate.reactive.sql.results.spi.ReactiveListResultsConsumer.lambda$addToResultsSupplier$5(ReactiveListResultsConsumer.java:141)
	at org.hibernate.reactive.sql.results.spi.ReactiveListResultsConsumer.lambda$consume$1(ReactiveListResultsConsumer.java:96)
	at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1150)
	at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
	at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2179)
	at io.vertx.core.Future.lambda$toCompletionStage$3(Future.java:602)
	at io.vertx.core.impl.future.FutureImpl$4.onSuccess(FutureImpl.java:176)
	at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:66)
	at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:259)
	at io.vertx.sqlclient.impl.QueryResultBuilder.tryComplete(QueryResultBuilder.java:88)
	at io.vertx.sqlclient.impl.QueryResultBuilder.tryComplete(QueryResultBuilder.java:32)
	at io.vertx.core.Promise.complete(Promise.java:66)
	at io.vertx.core.Promise.handle(Promise.java:51)
	at io.vertx.core.Promise.handle(Promise.java:29)
	at io.vertx.core.impl.future.FutureImpl$4.onSuccess(FutureImpl.java:176)
	at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:66)
	at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:259)
	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$4.onSuccess(FutureImpl.java:176)
	at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess$0(FutureBase.java:60)
	at io.vertx.core.impl.ContextImpl.execute(ContextImpl.java:312)
	at io.vertx.core.impl.DuplicatedContext.execute(DuplicatedContext.java:168)
	at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:57)
	at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:259)
	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.core.impl.future.PromiseImpl.handle(PromiseImpl.java:23)
	at io.vertx.sqlclient.impl.command.CommandResponse.fire(CommandResponse.java:46)
	at io.vertx.sqlclient.impl.SocketConnectionBase.handleMessage(SocketConnectionBase.java:324)
	at io.vertx.pgclient.impl.PgSocketConnection.handleMessage(PgSocketConnection.java:114)
	at io.vertx.sqlclient.impl.SocketConnectionBase.lambda$init$0(SocketConnectionBase.java:137)
	at io.vertx.core.impl.ContextImpl.emit(ContextImpl.java:342)
	at io.vertx.core.impl.ContextImpl.emit(ContextImpl.java:335)
	at io.vertx.core.net.impl.NetSocketImpl.handleMessage(NetSocketImpl.java:389)
	at io.vertx.core.net.impl.ConnectionBase.read(ConnectionBase.java:159)
	at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:153)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
	at io.vertx.pgclient.impl.codec.PgDecoder.fireCommandResponse(PgDecoder.java:52)
	at io.vertx.pgclient.impl.codec.PgCommandCodec.handleReadyForQuery(PgCommandCodec.java:133)
	at io.vertx.pgclient.impl.codec.PgDecoder.decodeReadyForQuery(PgDecoder.java:248)
	at io.vertx.pgclient.impl.codec.PgDecoder.channelRead(PgDecoder.java:107)
	at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1357)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:868)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:796)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:732)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:658)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998)
	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:1583)

Expected behavior

No exception is thrown, and querying FooEntity behaves as expected.

Actual behavior

The aforementioned exception is unexpectedly thrown

How to Reproduce?

Running ReproducerTest in the attached reproducer archive reproduces the error. Can use ./mvnw integration-test -Dtest=ReproducerTest

class_cast_bug_quarkus_reproducer.zip

Output of uname -a or ver

Darwin MACHINE_NAME 24.4.0 Darwin Kernel Version 24.4.0: Wed Mar 19 21:17:25 PDT 2025; root:xnu-11417.101.15~1/RELEASE_ARM64_T6020 arm64

Output of java -version

openjdk version "21.0.6" 2025-01-21 LTS OpenJDK Runtime Environment Corretto-21.0.6.7.1 (build 21.0.6+7-LTS) OpenJDK 64-Bit Server VM Corretto-21.0.6.7.1 (build 21.0.6+7-LTS, mixed mode, sharing)

Quarkus version or git rev

3.20.0

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions