Home > Enterprise >  JPA entity foreign key is a primary key from other entity
JPA entity foreign key is a primary key from other entity

Time:11-09

I'm sorry if this post title is not understandable

I have several tables in a Oracle database and I want to generate each entity in Spring Boot JPA.

This is a piece of I have:

CREATE TABLE T1 (
   C1 NUMBER(4) NOT NULL,
   C2 NUMBER(5) NOT NULL,
   C3 NUMBER(2) NOT NULL,
   C4 NUMBER(9) NOT NULL,
   C5 VARCHAR2(10 CHAR) NOT NULL,
   CONSTRAINT PK_T1 PRIMARY KEY (C1,C2,C3,C4)
);

CREATE TABLE T2 (
   C1 NUMBER(4) NOT NULL,
   C2 NUMBER(5) NOT NULL,
   C3 NUMBER(2) NOT NULL,
   C4 NUMBER(9) NOT NULL,
   C5 NUMBER(6) NOT NULL,
   C6 NUMBER(3) NOT NULL,
   C7 VARCHAR2(10 CHAR) NOT NULL,
   C8 VARCHAR2(20 CHAR) NOT NULL,
   CONSTRAINT PK_T2 PRIMARY KEY (C1,C2,C3,C4,C5,C6),
   CONSTRAINT FK_T2_T1 FOREIGN KEY (C1,C2,C3,C4) REFERENCES T1
);

I need to map this both tables to JPA entities but I can't figure out how to map them.

These are the entities classes in Java:

import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
import lombok.Data;
@Entity
@Table(name = "T1")
@Data
public class T1Bean implements Serializable {
   @EmbeddedId
   private T1PK pk;
   @Basic
   @Column(name = "C5", nullable = false)
   private String c5;
}
------------------
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import lombok.Data;
@Data
@Embeddable
public class T1PK implements Serializable {
   @Basic
   @Column(name = "C1", nullable = false)
   private int c1;
   @Basic
   @Column(name = "C2", nullable = false)
   private int c2;
   @Basic
   @Column(name = "C3", nullable = false)
   private int c3;
   @Basic
   @Column(name = "C4", nullable = false)
   private long c4;
}
------------------
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import lombok.Data;
@Entity
@Table(name = "T2")
@Data
public class T2Bean implements Serializable {
   @EmbeddedId
   private T2PK pk;
   @Basic
   @Column(name = "C7", nullable = false)
   private String c7;
   @Basic
   @Column(name = "C8", nullable = false)
   private String c8;
   @OneToOne
   private T1Bean t1Bean;
}
------------------
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import lombok.Data;
@Data
@Embeddable
public class T2PK implements Serializable {
   @Basic
   @Column(name = "C1", nullable = false)
   private int c1;
   @Basic
   @Column(name = "C2", nullable = false)
   private int c2;
   @Basic
   @Column(name = "C3", nullable = false)
   private int c3;
   @Basic
   @Column(name = "C4", nullable = false)
   private long c4;
   @Basic
   @Column(name = "C5", nullable = false)
   private int c5;
   @Basic
   @Column(name = "C6", nullable = false)
   private int c6;
}

Which annotation is missing in T2Bean entity to make looks good the mapping between each entity?

I only put the @OneToOne annotation but I don't know if is correct.

CodePudding user response:

First you just need to map two classes T1 and T2 these classes are considered as Bean or module or Entity

Entity T1

@Entity
@Table(name = "T1")
@Data
public class T1 implements Serializable {
@EmbeddedId
private <type> c1;
private <type> c2;
private <type> c3;
private <type> c4;

private T2 t2;
/* getters & setters */
@Column(name = "C1", nullable = false)
public String getC1(){
    return c1;
}

public void setC1(c1){
    this.c1 = c1;
}

// .... All other classes are the same

@OneToOne(fetch = FetchType.EAGER, targetEntity = T2.class)
public T2 getT2(){
    return t2;
}

public void setT2(t2){
    this.t2 = t2;
}

Entity T2

@Entity
@Table(name = "T2")
@Data
public class T2 implements Serializable {
@EmbeddedId
private <type> c1;
private <type> c2;
private <type> c3;
private <type> c4;
private <type> c5;
private <type> c6;
private <type> c7;
private <type> c8;

private T1 t1;
/* getters & setters */
@Column(name = "C1", nullable = false)
public String getC1(){
    return c1;
}

public void setC1(c1){
    this.c1 = c1;
}

//Foreigin key 
@OneToOne(fetch = FetchType.EAGER, targetEntity = T1.class)
@JoinColumn(name ="c1", nullable = false)
public T1 getT1(){
    return t1;
}

public void setT1(t1){
    this.t1 = t1;
}

CodePudding user response:

Thanks to the @chris comment.

I found the solution for T2Bean entity as below:

@Entity
@Table(name = "T2")
@Data
public class T2Bean implements Serializable {
   @EmbeddedId
   private T2PK pk;
   @Basic
   @Column(name = "C7", nullable = false)
   private String c7;
   @Basic
   @Column(name = "C8", nullable = false)
   private String c8;
   @ManyToOne(fetch = FetchType.EAGER)
   @JoinColumns({
         @JoinColumn(name = "c1",referencedColumnName = "c1",insertable = false,updatable = false),
         @JoinColumn(name = "c2",referencedColumnName = "c2",insertable = false,updatable = false),
         @JoinColumn(name = "c3",referencedColumnName = "c3",insertable = false,updatable = false),
         @JoinColumn(name = "c4",referencedColumnName = "c4",insertable = false,updatable = false),
   })
   private T1Bean t1Bean;
}

And the @Embeddable for T1 with the annotation @PrimaryKeyJoinColumn.

@Data
@Embeddable
@PrimaryKeyJoinColumn
public class T1PK implements Serializable {
   @Basic
   @Column(name = "C1", nullable = false)
   private int c1;
   @Basic
   @Column(name = "C2", nullable = false)
   private int c2;
   @Basic
   @Column(name = "C3", nullable = false)
   private int c3;
   @Basic
   @Column(name = "C4", nullable = false)
   private long c4;
}

With that entity, 2nd request doesn't work:

REQUEST 1:

{
    "pk": {
        "c1": 1,
        "c2": 2,
        "c3": 3,
        "c4": 998755544548
    },
    "c5": "John"
}

REQUEST 2:

{
    "pk": {
        "c1": 1,
        "c2": 2,
        "c3": 5,
        "c4": 998755544548,
        "c5": 55,
        "c6": 15
    },
    "c7": "Simon",
    "c8": "system"
}
  • Related