Skip to content

NullPointerException when retrieving @ManyToOne composite table with additional properties in @IdClass #2007

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
janek64 opened this issue Oct 8, 2024 · 3 comments · Fixed by #2058 or #2184
Assignees
Labels
bug Something isn't working
Milestone

Comments

@janek64
Copy link

janek64 commented Oct 8, 2024

When retrieving an entity that models a composite table between two other tables and uses an @IdClass that includes the IDs of the related entities and an additional property as the composite primary key, the query fails with a NullPointerException. The issue occurs in version >=2.4.0.Final, but not in 2.3.1.Final.

For example, given the following simple entities:

@Entity
@Table(name = "product")
public class Product {

    @Id
    @Column(name = "id")
    private UUID id;

    @Column(name = "name")
    private String name;

    // Constructor, Getter and Setter
}
@Entity
@Table(name = "customer")
public class Customer {

    @Id
    @Column(name = "id")
    private UUID id;

    @Column(name = "name")
    private String name;

    // Constructor, Getter and Setter
}

The entities are connected through the following relationship entity, which uses an @IdClass:

@Entity
@Table(name = "delivery")
@IdClass(DeliveryId.class)
public class Delivery {

    @Id
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "product_id", referencedColumnName = "id")
    private Product product;

    @Id
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "customer_id", referencedColumnName = "id")
    private Customer customer;

    @Id
    @Column(name = "additional_key")
    private String additionalKey;

    // Constructor, Getter, Setter, Equals, HashCode
}
public class DeliveryId implements Serializable {

    private UUID product;
    private UUID customer;
    private String additionalKey;

   // Getter, Setter, Equals, HashCode
}

When persisting exemplary entities and retrieving the Delivery relationship with a query such as

session.createQuery("SELECT d FROM Delivery d", Delivery.class).getResultList()

the following exception is thrown:

12:01:25.612 [vert.x-eventloop-thread-16] INFO  o.h.r.v.impl.DefaultVertxInstance - HR000003: Vert.x instance stopped
Exception in thread "main" java.util.concurrent.CompletionException: java.lang.NullPointerException: Cannot invoke "org.hibernate.reactive.sql.results.graph.ReactiveInitializer.getData(org.hibernate.sql.results.jdbc.spi.RowProcessingState)" because "initializer" is null
        at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:332)
        at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1177)
        at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2341)
        at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:144)
        at org.hibernate.reactive.util.async.impl.AsyncTrampoline.asyncWhile(AsyncTrampoline.java:216)
        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.ReactiveNonAggregatedIdentifierMappingInitializer.reactiveResolveKey(ReactiveNonAggregatedIdentifierMappingInitializer.java:64)
        at org.hibernate.reactive.sql.results.graph.embeddable.internal.ReactiveNonAggregatedIdentifierMappingInitializer.reactiveResolveKey(ReactiveNonAggregatedIdentifierMappingInitializer.java:25)
        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:601)
        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.lambda$emitSuccess$0(FutureBase.java:60)
        at io.vertx.core.impl.ContextImpl.execute(ContextImpl.java:298)
        at io.vertx.core.impl.DuplicatedContext.execute(DuplicatedContext.java:169)
        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:328)
        at io.vertx.core.impl.ContextImpl.emit(ContextImpl.java:321)
        at io.vertx.core.net.impl.NetSocketImpl.handleMessage(NetSocketImpl.java:388)
        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:1407)
        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:918)
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:994)
        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)
Caused by: java.lang.NullPointerException: Cannot invoke "org.hibernate.reactive.sql.results.graph.ReactiveInitializer.getData(org.hibernate.sql.results.jdbc.spi.RowProcessingState)" because "initializer" is null
        at org.hibernate.reactive.sql.results.graph.embeddable.internal.ReactiveNonAggregatedIdentifierMappingInitializer.lambda$reactiveResolveKey$1(ReactiveNonAggregatedIdentifierMappingInitializer.java:69)
        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)
        ... 79 more

Please find the following reproducer, which can be executed with ./gradlew run: hibernate-reactive-idclass-issue.zip

Best regards,
Janek

@DavideD DavideD self-assigned this Oct 8, 2024
@DavideD DavideD added this to the next milestone Oct 8, 2024
@markusdlugi
Copy link

Hi @DavideD, any progress on this one? Similar to #1979 and #2004, this bug also affects our Hibernate Reactive applications and is now the third issue blocking our upgrade to Quarkus 3.14 LTS or above. We'd really love to upgrade at some point in time... 😅

@DavideD
Copy link
Member

DavideD commented Nov 20, 2024

Not yet, I had to focus on the Hibernate ORM 7 upgrade.
Now that's almost done, I should be able to look into this soon.

@DavideD DavideD added problem A limitation or source of discomfort and removed problem A limitation or source of discomfort labels Dec 6, 2024
@DavideD DavideD removed their assignment Dec 17, 2024
dreab8 added a commit to dreab8/hibernate-reactive that referenced this issue Jan 4, 2025
dreab8 added a commit to dreab8/hibernate-reactive that referenced this issue Jan 4, 2025
dreab8 added a commit to dreab8/hibernate-reactive that referenced this issue Jan 4, 2025
@DavideD DavideD added the bug Something isn't working label Jan 7, 2025
DavideD added a commit to DavideD/hibernate-reactive that referenced this issue Jan 7, 2025
DavideD added a commit to DavideD/hibernate-reactive that referenced this issue Jan 7, 2025
DavideD pushed a commit to DavideD/hibernate-reactive that referenced this issue Jan 7, 2025
DavideD pushed a commit to DavideD/hibernate-reactive that referenced this issue Jan 7, 2025
DavideD added a commit to DavideD/hibernate-reactive that referenced this issue Jan 7, 2025
DavideD added a commit to DavideD/hibernate-reactive that referenced this issue Jan 7, 2025
@DavideD DavideD modified the milestones: next, 3.0.0.Beta2 Jan 7, 2025
DavideD pushed a commit that referenced this issue Jan 8, 2025
DavideD pushed a commit that referenced this issue Jan 8, 2025
DavideD added a commit that referenced this issue Jan 8, 2025
DavideD added a commit that referenced this issue Jan 8, 2025
@markusdlugi
Copy link

@DavideD, this bugfix hasn't been released yet, has it? Would it be possible to backport it to 2.4?

DavideD pushed a commit to DavideD/hibernate-reactive that referenced this issue Apr 7, 2025
DavideD pushed a commit to DavideD/hibernate-reactive that referenced this issue Apr 7, 2025
DavideD added a commit to DavideD/hibernate-reactive that referenced this issue Apr 7, 2025
DavideD added a commit to DavideD/hibernate-reactive that referenced this issue Apr 7, 2025
@DavideD DavideD linked a pull request Apr 7, 2025 that will close this issue
DavideD pushed a commit that referenced this issue Apr 7, 2025
DavideD pushed a commit that referenced this issue Apr 7, 2025
DavideD added a commit that referenced this issue Apr 7, 2025
DavideD added a commit that referenced this issue Apr 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
4 participants