Skip to content

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

@pardhiv-krishna

Description

@pardhiv-krishna

After #2245 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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions