mysqlhibernateforeign-keyshibernate-mappingcomposite-key

How to define composite foreign key mapping in hibernate?


I have two tables: users and userdetails as follows:

package com.example.easynotes.model;

import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(name = "users")
@IdClass(UserID.class)
public class User implements Serializable {

    @Id
    int id;

    @Id
    String name;

    String department;

    //getters and setters

}

The userdetails classes will be this:

public class UserDetails implements Serializable{

int id;

String name;

String address;

String otherFields;

//getters and setters

}

id and name in users is a composite primary and I want the same fields in userdetails to be the foreign key. How can I achieve this in hibernate ?


Solution

  • We need to put both key in @Embeddable to detach compound key thenafter, put it in User Entity using @EmbeddedId and map both primary key using Hibernate Relational Mapping...

    There are two option to Composite Primary Key:

    1. Using @EmbeddedId
    2. Using @IdClass()

    Here down is example:

    ----------------------------------- Using EmbeddedId -----------------------------------

    Compound primary key:

    @Embeddable
    public class UserIdName implements Serializable {
        int id;
        String name;
        
        // getter and setter
    }
    

    User:

    @Entity
    @Table(name = "users")
    public class USER{
        @EmbeddedId
        private UserIdName id;
    
        String department;
        
        @OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
        private Set<Userdetail> userdetail;
    
        // getter and setter
    }
    

    UserDetails:

    @Entity
    @Table(name = "Userdetail")
    public class Userdetail {
    
        @Id
        private int detail_id;
    
        @ManyToOne
        @JoinColumns({ @JoinColumn(name = "id", referencedColumnName = "id"),
                @JoinColumn(name = "name", referencedColumnName = "name") })
        private USER user;
    
        String address;
    
        String otherFields;
    
        // getter setter
    }
    

    ----------------------------------- Using IdClass -----------------------------------

    Compound primary key:

    public class UserIdName implements Serializable {
        int id;
        String name;
        
        // getter and setter
    }
    

    User:

    @Entity
    @Table(name = "users")
    @IdClass(UserIdName.class)
    public class USER{
        @Id
        int id;
    
        @Id
        String name;
    
        String department;
        
        @OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
        private Set<Userdetail> userdetail;
    
        // getter and setter
    }
    

    UserDetails:

    @Entity
    @Table(name = "Userdetail")
    public class Userdetail {
    
        @Id
        private int detail_id;
    
        @ManyToOne
        @JoinColumns({ @JoinColumn(name = "id", referencedColumnName = "id"),
                @JoinColumn(name = "name", referencedColumnName = "name") })
        private USER user;
    
        String address;
    
        String otherFields;
    
        // getter setter
    }
    

    -> If you wanna insert both foreign key manually try below code

    Put this code in UserDetails

    @ManyToOne
    @JoinColumn(name = "id", referencedColumnName = "id", insertable = false, updatable = false)
    @JoinColumn(name = "name", referencedColumnName = "name", insertable = false, updatable = false)
    private USER user;
    
    @Column(name="id")
    private int id;
    
    @Column(name="name")
    private String name
    
    // don't forget to put getter setter
    

    User Table:

    enter image description here

    User Detail Table:

    enter image description here