Skip to content

Usage of element collection triggers NPE during saving in Hibernate with Jakarta Data #48712

@nh2297

Description

@nh2297

Describe the bug

In Quarkus 3.24.1 an NPE occurs during saving with Hibernate 7 and Jakarta Data when an ElementCollection is used. It is not triggered if insert is used instead. This behaviour seems to be specific to the save call in the repository

Parent:

@Entity
@Table(name = "parent")
public class Parent {

    @Id
    private UUID id;

    @ElementCollection(fetch = FetchType.EAGER)
    @CollectionTable(name = "parent_child_embedded_entity", joinColumns = @JoinColumn(name = "parent_id"))
    private Set<ChildEmbeddedEntity> childEmbeddedEntities;

}

Child:

package org.acme;

import jakarta.persistence.Embeddable;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

@Embeddable
public class ChildEmbeddedEntity {

    @NotBlank
    private String test;

    @NotNull
    private String test2;
}

Repository:

package org.acme;

import jakarta.data.repository.CrudRepository;
import jakarta.data.repository.Repository;
import java.util.UUID;

@Repository
public interface StartRepository extends CrudRepository<Parent, UUID> {
}

Simple test case:

package org.acme;


import io.quarkus.test.TestTransaction;
import io.quarkus.test.junit.QuarkusTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;

@QuarkusTest
public class ParentTest {

    @Inject
    StartRepository startRepository;


    @Test
    @TestTransaction
    void save() {
        startRepository.save(new Parent());
    }
}

Note: Also when @OneToMany is used without mappedBy a NPE is thrown.
Example of that:

package org.acme;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.util.Set;
import java.util.UUID;

@Entity
@Table(name = "parent_one_to_many")
public class ParentOneToMany {

    @Id
    private UUID id;

    @OneToMany
    private Set<ChildToManyEntity> childToManyEntities;

}
package org.acme;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import java.util.UUID;

@Entity
public class ChildToManyEntity {

    @Id
    private UUID id;
}

Results in the same NPE.

Expected behavior

Entity is saved in DB

Actual behavior

Following NPE is thrown:

java.lang.NullPointerException: Cannot invoke "org.hibernate.event.spi.EventSource.getPersistenceContextInternal()" because "source" is null
        at org.hibernate.event.spi.AbstractCollectionEvent.getLoadedOwnerOrNull(AbstractCollectionEvent.java:53)
        at org.hibernate.event.spi.PreCollectionUpdateEvent.<init>(PreCollectionUpdateEvent.java:25)
        at org.hibernate.internal.StatelessSessionImpl.lambda$firePreUpdate$8(StatelessSessionImpl.java:647)
        at org.hibernate.event.service.internal.EventListenerGroupImpl.fireLazyEventOnEachListener(EventListenerGroupImpl.java:126)
        at org.hibernate.internal.StatelessSessionImpl.firePreUpdate(StatelessSessionImpl.java:646)
        at org.hibernate.internal.StatelessSessionImpl.lambda$removeAndRecreateCollections$2(StatelessSessionImpl.java:435)
        at org.hibernate.internal.StatelessSessionImpl.lambda$forEachOwnedCollection$13(StatelessSessionImpl.java:705)
        at org.hibernate.metamodel.mapping.internal.ImmutableAttributeMappingList.forEach(ImmutableAttributeMappingList.java:41)
        at org.hibernate.persister.entity.AbstractEntityPersister.visitAttributeMappings(AbstractEntityPersister.java:5879)
        at org.hibernate.internal.StatelessSessionImpl.forEachOwnedCollection(StatelessSessionImpl.java:685)
        at org.hibernate.internal.StatelessSessionImpl.removeAndRecreateCollections(StatelessSessionImpl.java:433)
        at org.hibernate.internal.StatelessSessionImpl.upsert(StatelessSessionImpl.java:500)
        at org.hibernate.internal.StatelessSessionImpl.upsert(StatelessSessionImpl.java:458)
        at io.quarkus.hibernate.orm.runtime.session.TransactionScopedStatelessSession.upsert(TransactionScopedStatelessSession.java:827)
        at io.quarkus.hibernate.orm.runtime.StatelessSessionLazyDelegator.upsert(StatelessSessionLazyDelegator.java:473)
        at org.hibernate.StatelessSession_n3iQrBj-uHEgbplTFsa_2PHff-k_Synthetic_ClientProxy.upsert(Unknown Source)
        at org.acme.StartRepository_.save(StartRepository_.java:115)
        at org.acme.StartRepository_.save(StartRepository_.java:34)
        at org.acme.ParentTest.save(ParentTest.java:19)
        at org.acme.ParentTest_Subclass.save$$superforward(Unknown Source)
        at org.acme.ParentTest_Subclass$$function$$1.apply(Unknown Source)
        at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:73)
        at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:62)
        at io.quarkus.narayana.jta.runtime.interceptor.TestTransactionInterceptor.intercept(TestTransactionInterceptor.java:45)
        at io.quarkus.narayana.jta.runtime.interceptor.TestTransactionInterceptorGenerated_Bean.intercept(Unknown Source)
        at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
        at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:30)
        at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:27)
        at org.acme.ParentTest_Subclass.save(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at io.quarkus.test.junit.QuarkusTestExtension.runExtensionMethod(QuarkusTestExtension.java:1000)
        at io.quarkus.test.junit.QuarkusTestExtension.interceptTestMethod(QuarkusTestExtension.java:848)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1597)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1597)

How to Reproduce?

Reproducer project: https://github.com/nh2297/element-collection-issue

Output of uname -a or ver

Darwin 24.5.0 Darwin Kernel Version 24.5.0: Tue Apr 22 19:53:27 PDT 2025; root:xnu-11417.121.6~2/RELEASE_ARM64_T6041 arm64

Output of java -version

21

Quarkus version or git rev

3.24.1

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

Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937) Maven home: /opt/homebrew/Cellar/maven/3.9.9/libexec Java version: 23.0.2, vendor: Homebrew, runtime: /opt/homebrew/Cellar/openjdk/23.0.2/libexec/openjdk.jdk/Contents/Home Default locale: en_DE, platform encoding: UTF-8 OS name: "mac os x", version: "15.5", arch: "aarch64", family: "mac"

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/hibernate-ormHibernate ORMkind/bug-thirdpartyBugs that are caused by third-party components and not causing a major dysfunction of core Quarkus.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions