Skip to content

EclipseLink NullPointerException: Cannot invoke "java.lang.Number.intValue()" when nested record embeddables #33662

@njr-11

Description

@njr-11

After #29460 was fixed, most of the commented out tests worked and could be enabled, but EclipseLink gets a NullPointerException on one that has a record embeddable within another record embeddable,

// entity per orm.xml
public class CylinderEntity extends Object {
    public java.lang.String getCID() ...
    public Cylinder$Coordinate getCenter() ...
    public Cylinder$Side getSide() ...
    public void setCID(java.lang.String) ...
    public void setCenter(Cylinder$Coordinate) ... 
    public void setSide(Cylinder$Side) ...
}

public record Cylinder(String cID, Coordinate center, Side side) {
    public static record Coordinate(int x, int y) {}
    public static record Side(Coordinate a, Coordinate b) {}
}

From orm.xml,

  <entity class="test.jakarta.data.web.eclipselink.CylinderEntity">
    <table name="Cylinder"/>
    <attributes>
      <id name="cID" access="FIELD">
      </id>
      <embedded name="center" access="FIELD">
        <attribute-override name="x">
          <column name="CENTER_X"/>
        </attribute-override>
        <attribute-override name="y">
          <column name="CENTER_Y"/>
        </attribute-override>
      </embedded>
      <embedded name="side" access="FIELD">
        <attribute-override name="a.x">
          <column name="SIDE_A_X"/>
        </attribute-override>
        <attribute-override name="a.y">
          <column name="SIDE_A_Y"/>
        </attribute-override>
        <attribute-override name="b.x">
          <column name="SIDE_B_X"/>
        </attribute-override>
        <attribute-override name="b.y">
          <column name="SIDE_B_Y"/>
        </attribute-override>
      </embedded>
    </attributes>
  </entity>

  <embeddable class="test.jakarta.data.web.eclipselink.Cylinder$Coordinate">
    <attributes>
      <basic name="x" access="FIELD">
        <column nullable="false"/>
      </basic>
      <basic name="y" access="FIELD">
        <column nullable="false"/>
      </basic>
    </attributes>
  </embeddable>

  <embeddable class="test.jakarta.data.web.eclipselink.Cylinder$Side">
    <attributes>
      <embedded name="a" access="FIELD">
      </embedded>
      <embedded name="b" access="FIELD">
      </embedded>
    </attributes>
  </embeddable>

Per the above,
center is an embeddable of record type Coordinate under CylinderEntity.
side is an embeddable of record type Side under CylinderEntity.
a is an embeddable of record type Coordinate under Side.
b is an embeddable of record type Coordinate under Side.

EclipseLink creates the following table:

CREATE TABLE Cylinder (CID VARCHAR(255) NOT NULL, CENTER_X INTEGER, CENTER_Y INTEGER, SIDE_A_X INTEGER, SIDE_A_Y INTEGER, SIDE_B_X INTEGER, SIDE_B_Y INTEGER, PRIMARY KEY (CID))

The following JPQL is sent to EclipseLink:

SELECT NEW test.jakarta.data.web.eclipselink.Cylinder(o.cID, o.center, o.side) FROM CylinderEntity o WHERE (o.center.x=?1 AND o.center.y=?2) ORDER BY o.side.b.y, o.side.b.x, o.cID

From that, EclipseLink generates the following SQL:

SELECT CID, CENTER_X, CENTER_Y, SIDE_A_X, SIDE_A_Y, SIDE_B_X, SIDE_B_Y FROM Cylinder WHERE ((CENTER_X = ?) AND (CENTER_Y = ?)) ORDER BY SIDE_B_Y, SIDE_B_X, CID

EclipseLink fails with the following NullPointerException when attempting to obtain the result:

jakarta.persistence.PersistenceException: java.lang.IllegalArgumentException: java.lang.NullPointerException: Cannot invoke "java.lang.Number.intValue()" because the return value of "sun.invoke.util.ValueConversions.primitiveConversion(sun.invoke.util.Wrapper, Object, boolean)" is null
at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:488)
at io.openliberty.data.internal.persistence.QueryInfo.find(QueryInfo.java:1933)
at io.openliberty.data.internal.persistence.QueryInfo.find(QueryInfo.java:1825)
at io.openliberty.data.internal.persistence.RepositoryImpl.invoke(RepositoryImpl.java:555)
Caused by: java.lang.IllegalArgumentException: java.lang.NullPointerException: Cannot invoke "java.lang.Number.intValue()" because the return value of "sun.invoke.util.ValueConversions.primitiveConversion(sun.invoke.util.Wrapper, Object, boolean)" is null
at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:70)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
at org.eclipse.persistence.internal.descriptors.RecordInstantiationPolicy.newRecord(RecordInstantiationPolicy.java:87)
at org.eclipse.persistence.internal.descriptors.RecordInstantiationPolicy.buildNewInstance(RecordInstantiationPolicy.java:66)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildNewRecordInstance(ObjectBuilder.java:805)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildNewRecordInstance(ObjectBuilder.java:782)
at org.eclipse.persistence.mappings.AggregateObjectMapping.buildAggregateFromRow(AggregateObjectMapping.java:475)
at org.eclipse.persistence.queries.ReportQueryResult.processItem(ReportQueryResult.java:277)
at org.eclipse.persistence.queries.ReportQueryResult.processConstructorItem(ReportQueryResult.java:153)
at org.eclipse.persistence.queries.ReportQueryResult.buildResult(ReportQueryResult.java:120)
at org.eclipse.persistence.queries.ReportQueryResult.<init>(ReportQueryResult.java:99)
at org.eclipse.persistence.queries.ReportQuery.buildObject(ReportQuery.java:657)
at org.eclipse.persistence.queries.ReportQuery.buildObjects(ReportQuery.java:735)
at org.eclipse.persistence.queries.ReportQuery.executeDatabaseQuery(ReportQuery.java:976)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:937)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1256)
at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:485)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1344)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:3018)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1866)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1848)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1813)
at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:263)
at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:480)
Caused by: java.lang.NullPointerException: Cannot invoke "java.lang.Number.intValue()" because the return value of "sun.invoke.util.ValueConversions.primitiveConversion(sun.invoke.util.Wrapper, Object, boolean)" is null
at java.base/sun.invoke.util.ValueConversions.unboxInteger(ValueConversions.java:81)
at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62) 

It should be noted that if the record Side is switched to a class that is not a record, everything else is the same as above except that it runs successfully without error,

    public static class Side {
        public Coordinate a, b;

        public Side() {
        }

        public Side(Coordinate a, Coordinate b) {
            this.a = a;
            this.b = b;
        }

        public Coordinate a() {
            return a;
        }

        public Coordinate b() {
            return b;
        }

        @Override
        public String toString() {
            return "Side {a=" + a + ", b=" + b + "}";
        }
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis bug is not present in a released version of Open Libertyin:JPAteam:Blizzard

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions