Search code examples
hibernatespring-data-jpajoincolumn

Multi joinColumn Jpa


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:

https://github.com/mcau92/java-exercises-projects/tree/master/com.cauduro.example.jpa/com.cauduro.example.mutlijoin

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.