Issue
Hi everyone and thanks for your attention!. Like title says i'm facing a problem trying to connect 3 entities in jpa, where two of them are connected with 3 keys (one Pk and two Fks). i create a simple project on github that works perfectly but i need to change a little bit that scenario. this is the link to the source code:
What i need now is to update the relation between Parent and Child, i need to connect both with 3 columns, the parentID(pid) + GranParentId (gid) + fk2 , what it should look like is something like this:
//PARENT
@Entity
public class Parent implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer pid;
@ManyToOne
@JoinColumn(name = "gid", referencedColumnName = "gid")
private GrandParent grandparent;
@Column(name = "fk2")
private String fk2;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "parent")
private Set<Child> childs;
//getters and setters
}
//CHILD
@Entity
public class Child implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
@ManyToOne
@JoinColumn(name = "pid", referencedColumnName = "pid")
@JoinColumn(name = "gid", referencedColumnName = "gid")
@JoinColumn(name = "fk2", referencedColumnName = "fk2")
private Parent parent;
//GETTERS AND SETTERS
}
This give me an error because i think i'm trying to share pk also. I was able to replicate, in the source code, a similar scenario where i connected only gid and fk2 to Child, i probably think that i need an embeddable class where store my id and the others key.
Thanks to everybody!
Solution
Try to use IdClass
,so; the parent class should have multiple primary key, which is called composite key, and by referencing it to the child class, the JPA now will know that there are a multiple join columns should be injected in the child class.
Example:
// Id Class
public class ParentId implements Serializable{
@Id
private Integer key1;
@Id
private Integer key2;
}
// Parent
@Entity
@IdClass(ParentId.class)
public class Parent implements Serializable {
@Id
private Integer key1;
@Id
private Integer key2;
}
// Child
@Entity
public class Child implements Serializable {
@Id
private Integer childId;
@ManyToOne
@JoinColumn(name = "key1", referencedColumnName = "key1")
@JoinColumn(name = "key2", referencedColumnName = "key2")
private Parent parent;
}
I'm not sure if this will help you but you can read this article for more details.
Answered By - Ibrahim AlTamimi
Answer Checked By - Marilyn (JavaFixing Volunteer)