eclipse-ee4j/eclipselink

EntityManager#getReference throws NPE for entity with composite id

Opened this issue · 0 comments

Describe the bug
If calling EntityManager#getReference on a fresh (!) entity manager for an entity with a composite key, a NPE is thrown.
This also only occurs, if static weaving is used.

java.lang.NullPointerException: Cannot invoke "org.eclipse.persistence.internal.queries.EntityFetchGroup.setOnEntity(Object, org.eclipse.persistence.internal.sessions.AbstractSession)" because the return value of "org.eclipse.persistence.descriptors.FetchGroupManager.getIdEntityFetchGroup()" is null
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.getReference(UnitOfWorkImpl.java:6204)
	at org.eclipse.persistence.internal.jpa.EntityManagerImpl.getReference(EntityManagerImpl.java:1503)
	at eclipselink.jpa.bugtest.TestBug.getReferenceByCompositeKeyTest(TestBug.java:38)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:93)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:529)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:756)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)

To Reproduce

Start class TestBug.java in branch "bug-entitymanager-getReference" in repository git@github.com:vseibt/eclipselink-jpa-testcase-202402.git as the only test.

If the entity manager is already used by other tests, this error does not occur.

This branch contains static weaving using de.empulse.eclipselink:staticweave-maven-plugin:1.0.0.

There is also a class TestOk, which gets the same entity using find and an entity with a single id using getReference.

Code leading to NPE:

            em.getTransaction().begin();
            var id = new TestEntityPersonId("Stan", "Dandeliver");
            var testPerson = em.getReference(TestEntityPerson.class, id);

with entity

@Entity
@IdClass(TestEntityPersonId.class)
@Table(name = "TEST_TAB_PERSON")
public class TestEntityPerson {

    @Id
    @Column(name = "FIRST_NAME")
    private String firstName;

    @Id
    @Column(name = "LAST_NAME")
    private String lastName;

    public TestEntityPerson() {
    }
}

and id class

public class TestEntityPersonId {

    private String firstName;

    private String lastName;

    public TestEntityPersonId() {
    }

    public TestEntityPersonId(String firstName, String lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
    }
}

Table created using

CREATE TABLE TEST_TAB_PERSON (FIRST_NAME VARCHAR(20) NOT NULL, LAST_NAME VARCHAR(20) NOT NULL, PRIMARY KEY(FIRST_NAME, LAST_NAME));
INSERT INTO TEST_TAB_PERSON (FIRST_NAME, LAST_NAME) VALUES ('Stan', 'Dandeliver');
  • EclipseLink version 4.0.2
  • Java/JDK version 17

Expected behavior
EntityManager#getReference should not throw a NPE.