简体   繁体   中英

Spring Boot Jpa relationship with part of Embeded Id

I am creating entity relationships in Spring Boot data JPA. Since those tables being legacy I am not able to modify or add columns. Issue is I am getting error if point part of embedded Id.

My entity classes looks like below:

Class Customer {
   @EmbededId
   private CustomerPk id;
   
   @Column("NAME")
   private String name; 
   
   @OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL, mappedBy="customerDetails")
   private List<Purchase> purchaseDetails;
   ...
}

@Embeddable
Class CustomerPk {
   @Column("CUSTOMER_ID")
   private String customerId
       
   @Column("PURCHASE_ID")
   private String productId; 

   @Column("PURCHASE_DATE")
   private String date; 

   
 }

Purchase Entity looks like below:

Class Purchase {
       @EmbededId
       private PurchasePK id;
       
       @Column("TRANSACTION_NAME")
       private String transactionName; 
       
       @ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
       @JoinColumns({
         @JoinColumn(name="CUSTOMER_ID" referencedColumnName="CUSTOMER_ID")
         @JoinColumn(name="PURCHASE_ID" referencedColumnName="PURCHASE_ID")
       )}
       private Customer customerDetails;
       ...
    }

    @Embeddable
    Class PurchasePK {
       @Column("CUSTOMER_ID")
       private String customerId
           
       @Column("PURCHASE_ID")
       private String productId; 

       @Column("TRANSACTION_DATE")
       private String date; 
     }

With above structure I am getting org.hibernate.AnnotationException: referencedColumnNames(CUSTOMER_ID, PURCHASE_ID) of Purchase.customerDetails referencing Customer not mapped to a single property.

If I remove date property from CustomerPK, I am able to make the server up. But with current requirement I need date to be part of the CustomerPK class.

I think if I use part of the composite key as Join Columns I am getting this error.

Working version:

@Entity
public class Customer {
    @EmbeddedId
    private CustomerPk id;

    @Column(name = "NAME")
    private String name;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "customerDetails")
    private List<Purchase> purchaseDetails;
}

@Embeddable
public class CustomerPk implements Serializable {
    @Column(name = "CUSTOMER_ID")
    private String customerId;

    @Column(name = "PURCHASE_ID")
    private String productId;

    @Column(name = "PURCHASE_DATE")
    private String date;
}

@Entity
public class Purchase {
    @EmbeddedId
    private PurchasePK id;

    @Column(name = "TRANSACTION_NAME")
    private String transactionName;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumns({
            @JoinColumn(name = "CUSTOMER_ID", referencedColumnName = "CUSTOMER_ID", insertable = false, updatable = false),
            @JoinColumn(name = "PURCHASE_ID", referencedColumnName = "PURCHASE_ID", insertable = false, updatable = false),
            @JoinColumn(name = "PURCHASE_DATE", referencedColumnName = "PURCHASE_DATE", insertable = false, updatable = false)
    })
    private Customer customerDetails;
}

@Embeddable
public class PurchasePK implements Serializable {
    @Column(name = "CUSTOMER_ID")
    private String customerId;

    @Column(name = "PURCHASE_ID")
    private String productId;

    @Column(name = "TRANSACTION_DATE")
    private String date;
}

Conclusion:

The provided information from @Ray was valid, you missed adding the required join columns to represent the full entity relation, regarding your note for the same @Ray point, yes you are right both columns usage is different but also both columns have their own name which it will not override any row value on runtime.

The result of the above tables and representation is as follows:


create table customer
(
    customer_id   varchar(255) not null,
    purchase_date varchar(255) not null,
    purchase_id   varchar(255) not null,
    name          varchar(255),
    primary key (customer_id, purchase_date, purchase_id)
);
create table purchase
(
    customer_id      varchar(255) not null,
    transaction_date varchar(255) not null,
    purchase_id      varchar(255) not null,
    transaction_name varchar(255),
    purchase_date    varchar(255),
    primary key (customer_id, transaction_date, purchase_id)
);
alter table purchase
    add constraint FK6rkrb8rq8x56kai7g5gm32d1y foreign key (customer_id, purchase_date, purchase_id) references customer;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM