Java Spring Data JPA Composite ID with foreign key

I am making a Spring web service to learn more about it and I am currently mapping the database. I have a table that has a composite ID, where one of the ID’s is a foreign key to another table (ManytoOne).

Creditors Creditor_Invoices
ID Creditor_ID
name Invoice_ID

As anywhere you buy something they use their own way of making ID’s it has a composite ID like this. My Current code: Serializable class CInvoiceId:

import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import java.io.Serializable;
import java.util.Objects;

@Embeddable
public class CInvoiceId implements Serializable {
    @ManyToOne
    @JoinColumn(name = "creditors_id", nullable = false)
    private Creditor cInvoiceCreditorId;
    @Column(name = "invoice_id", nullable = false)
    private String cInvoiceId;

    public CInvoiceId(Creditor creditor, String cInvoiceId){
        this.cInvoiceCreditorId = creditor;
        this.cInvoiceId = cInvoiceId;
    }

    //Setters, Getters, Equals and Hash
}

My Creditor class

import javax.persistence.*;
import java.util.List;

@Entity
@Table(name = "creditors")
public class Creditor {
    @Id
    @GeneratedValue
    @Column(name = "id")
    private int creditorId;

    @Column(name = "name",nullable = false)
    private String creditorName;

    @OneToMany(mappedBy = "cInvoiceCreditorId")
    private List<CInvoice> cInvoices;
}

My CInvoice class:

import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;

@Entity
@Table(name = "c_invoices")
public class CInvoice {
    @EmbeddedId
    private CInvoiceId cInvoiceID;
}

When I start it to try and test it I get the error that it can not find the mapped by from the creditor class, but I don’t know what I should map it to as the ID is now made in the CInvoiceId class. What should it be?

Regards Dany

Answer

You can use “derived identities” to map these classes:

Creditor:

@Entity
@Table(name = "creditors")
public class Creditor {
    @Id
    @GeneratedValue
    @Column(name = "id")
    private int id;

    @Column(name = "name",nullable = false)
    private String name;

    @OneToMany(mappedBy = "creditor")
    private List<CInvoice> invoices;
}

CInvoiceId:

@Embeddable
public class CInvoiceId implements Serializable {
    @Column(name = "invoice_id", nullable = false)
    private String invoiceID;

    private int creditorID; // corresponds to PK type of Creditor

    // ...
}

CInvoice:

@Entity
@Table(name = "c_invoices")
public class CInvoice {
    @EmbeddedId
    private CInvoiceId id;

    @MapsId("creditorID") // maps creditorID attribute of embedded id
    @ManyToOne
    @JoinColumn(name = "creditors_id", nullable = false)
    Creditor creditor;
}

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