JPA eclipse two foreign keys @IdClass implementation errors

跟風遠走 提交于 2021-01-05 08:55:52

问题


I'm very new to Java EE and JPA/Eclipselink, so please bear with me. I'm trying to create a @Id for a table with no primary key and two composite keys, I tried to apply from a solution I read here by using @IdClass to mark the two foreign keys as a composite key, but I get this error when compiling and deploying the server.

Exception Description: Invalid composite primary key specification. The names of the primary key fields or properties in the primary key class [com.owl.server.objects.SaleDetails] and those of the entity bean class [class com.owl.server.objects.SaleDetails] must correspond and their types must be the same. Also, ensure that you have specified ID elements for the corresponding attributes in XML and/or an @Id on the corresponding fields or properties of the entity class.. Please see server.log for more details.

Must I change the field types to be the same? Or is there another way?

Products table and corresponding Entity

@Entity
@Table(name="products")
public class Product implements Serializable {
    
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "product_id", nullable = false)
   private String product_id;
   
   // ...
}

Sales Table and corresponding Entity

@Entity
@Table(name="Sales")
public class Sale implements Serializable{
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "sale_id", nullable = false)
    private int sale_id;

    // ...
}

Sale_details Table and Entity (Causes Errors)

public class SaleDetails implements Serializable {

    private int saleid_fk;
    private String productid_fk;
    private int quantity_sold;
    private String prescription;
    
    public SaleDetails() {
    }
    
    public SaleDetails(int saleid_fk, String productid_fk, int quantity_sold){
        this.saleid_fk = saleid_fk;
        this.productid_fk = productid_fk;
        this.quantity_sold = quantity_sold;
    }
}

Sale_details entity class

@Entity
@IdClass(SaleDetails.class)
@Table(name = "sale_Details")
public class Sale_details {
    
   @Id
   private int saleid_fk;
    
   @Id
   private String productid_fk;
}

Here is the full stack trace error:

[2020-12-24 11:43:50,553] Artifact server:war exploded: java.io.IOException: com.sun.enterprise.admin.remote.RemoteFailureException: Error occurred during deployment: Exception while preparing the app : Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.7.7.payara-p3): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [owlJPA] failed.
Internal Exception: Exception [EclipseLink-7150] (Eclipse Persistence Services - 2.7.7.payara-p3): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Invalid composite primary key specification. The names of the primary key fields or properties in the primary key class [com.owl.server.objects.SaleDetails] and those of the entity bean class [class com.owl.server.objects.Sale_details] must correspond and their types must be the same. Also, ensure that you have specified ID elements for the corresponding attributes in XML and/or an @Id on the corresponding fields or properties of the entity class.. Please see server.log for more details.

回答1:


Idclass value should not be the same class of Entity 'SaleDetails'

    @Entity
    @IdClass(PK.class)
    public static class SystemUser{
        @Id
        private String subsystem;

        @Id
        private String username;

        public PK getId(){
            return new PK(subsystem, username);
        }

        public void setId(PK id){
            this.subsystem = id.subsystem;
            this.username = id.username;
        }
    }

    public static class PK implements Serializable {

        private String subsystem;

        private String username;

        public PK(String subsystem, String username) {
            this.subsystem = subsystem;
            this.username = username;
        }
    }



回答2:


You can used "derived identities"; and this is the way to map the relationships:

@Embeddable
public class SaleDetailId {
    @Column(name = "product_id")
    String productId;  // corresponds to PK type of Product

    @Column(name = "sale_id")
    int saleId; // corresponds to PK type of Sale 
}


@Entity
@Table(name = "sale_details")
public class SaleDetail {
    @EmbeddedId
    SaleDetailId id;

    // id attribute mapped by join column default 
    @MapsId("saleId") // maps saleId attribute of embedded id 
    @ManyToOne
    private Sale sale;

    // id attribute mapped by join column default 
    @MapsId("productId") // maps productId attribute of embedded id 
    @ManyToOne
    private Product product;

    @Column(name = "quantity_sold")
    private int quantitySold;
    
    public SaleDetails(Sale sale, Product product, int quantity_sold){
        this.sale = sale;
        this.product = product;
        this.quantity_sold = quantity_sold;
    }
    // ...
}

Derived identities are discussed (with examples) in the JPA 2.2 spec in section 2.4.1.



来源:https://stackoverflow.com/questions/65444874/jpa-eclipse-two-foreign-keys-idclass-implementation-errors

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!