eclipse-ee4j / eclipselink

Eclipselink project
https://eclipse.dev/eclipselink/
Other
196 stars 167 forks source link

Java record as Embeddable rejected with NoSuchMethodException in EclipseLink #2214

Open Riva-Tholoor-Philip opened 1 month ago

Riva-Tholoor-Philip commented 1 month ago

The following error occurred when we tried to define an entity with an embeddable that is a Java record, which is supposed to be allowed in Jakarta Persistence 3.2:

[7/18/24, 16:07:23:910 CDT] 0000004c eclipselink.ps                                               E CWWKD0292E: Exception [EclipseLink-0] (Eclipse Persistence Services - 5.0.0-B02.v202404111748): org.eclipse.persistence.exceptions.IntegrityException
Descriptor Exceptions: 
---------------------------------------------------------

Exception [EclipseLink-63] (Eclipse Persistence Services - 5.0.0-B02.v202404111748): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The instance creation method [test.jakarta.data.jpa.web.Point.<Default Constructor>], with no parameters, does not exist, or is not accessible.
Internal Exception: java.lang.NoSuchMethodException: test.jakarta.data.jpa.web.Point.<init>()
Descriptor: RelationalDescriptor(test.jakarta.data.jpa.web.Point --> [DatabaseTable(WLPSegment)])

Entity:

@Entity
public class Segment {

    @GeneratedValue
    @Id
    public Long id;

    @Embedded
    @Column(nullable = false)
    public Point pointA;

    @Embedded
    @Column(nullable = false)
    public Point pointB;
}

Embeddable/record:

@Embeddable
public record Point(int x, int y) {
}

It is complaining that the record needs a default constructor. Even if I add one, which should not be necessary,

    public Point() {
        this(0, 0);
    }

then it fails a little later on with a different error about being unable to set values on the embeddable. It seems like EclipseLink doesn't realize it needs to treat the Java record embeddable differently than a normal embeddable.

Also, if I try working around this by not using Java records, and switching to a Java class for the embeddable, it still get's an unexpected failure where it seems that EclipseLink has failed to disambiguate the embeddable attributes in the database when the entity has two attributes of the same embeddable type:

java.sql.SQLSyntaxErrorException: Column name 'X' appears more than once times in the column list of an INSERT statement. Error Code: 20000 Call: INSERT INTO Segment (ID, X, Y, X, Y) VALUES (?, ?, ?, ?, ?) 
rfelcman commented 1 month ago

Java Record was implemented by https://github.com/eclipse-ee4j/eclipselink/pull/2163 It's not available in 5.0.0-B02.v202404111748, please try latest Maven snapshot like https://jakarta.oss.sonatype.org/content/groups/staging/org/eclipse/persistence/eclipselink/5.0.0-SNAPSHOT/eclipselink-5.0.0-20240718.131610-56.jar

lukasj commented 2 weeks ago

@Riva-Tholoor-Philip can you check current state, please?

Riva-Tholoor-Philip commented 2 weeks ago

Sure @lukasj