Hibernate mappings are one of the key features of Hibernate. They establish the relationship between two database tables as attributes in your model. That allows you to easily navigate the associations in your model and Criteria queries.
You can establish either unidirectional or bidirectional i.e you can either model them as an attribute on only one of the associated entities or on both. It will not impact your database mapping tables, but it defines in which direction you can use the relationship in your model and Criteria queries.
The relationship that can be established between entities are-
- One To One – It represent one to one relationship between two tables.
- One To Many/Many To one – It represents the one to many relationship between two tables.
- Many To Many – It represents thew many to many relationship between two tables.
You all must have heard about these relationship. In this blog, you will learn about all relationship using Hibernate.
One to One
There is One to One relationship between Address. Although Address must not be an Entity as it is a value type but for this Example we will consider Address as a separate Entity.
For One to One relationship, we need to simply annotate the data member of the corresponding class with @OneToOne. After running the application if we look after the table created by the hibernate , we will found that the user_details table has all the field i.e id , userName along with a foreign key of address table column ( In this example ). If we want to acheive two way binding like User object should have Address and viceversa. Then we have to make the User object inside Address class and annotate it with @OneToOne. Then, the address table will also contain the foreign key of user column.
You will see the name of field in both the table will be default depending on table name but to change the default implementation , we have to annotate it with @JoinColumn with a attribute name.
Address.java
package com.innovatnm.demohibernate.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToOne; @Entity public class Address { @Id @GeneratedValue private int id; private String street; private String city; @OneToOne(mappedBy="address") private User user; public Address() {} public Address(int id, String street, String city) { this.id = id; this.street = street; this.city = city; } public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } public String getCity() { return city; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public void setCity(String city) { this.city = city; } public int getId() { return id; } public void setId(int id) { this.id = id; } }
One to Many/Many to One
There is One to Many relationship between User and Mobile . As one user can have more than one Mobile . And Many to One relationship between Mobile and User.
For One to Many relationship , we have to annotate in same manner as above with @OneToMany to collection type data member. After running the application if we look after the table created by the hibernate , we will found that the hibernate is making a new table for mapping of user_details table and mobile table( In this example ). For two way binding we annotate the user inside the Mobile class with @ManyToOne.
You will see the mapping table and its column name will have default name generated based on the two tables but to change the default implementation, we will annotate it @JoinTable and the attribute name in this is to change the name of mapping table and attribute joinColumns for the primary key of the same class ( User in this case ) and inverseJoinColumns for the primary key of corresponding class ( Mobile in this case ).
Mobile.java
package com.innovatnm.demohibernate.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; @Entity public class Mobile { @Id @GeneratedValue private int id; private String brand; private String model; @ManyToOne @JoinColumn(name="user_id") private User user; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public String getModel() { return model; } public void setModel(String model) { this.model = model; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
Many to Many
There is Many to Many relationship between User and Vehicle. We will let consider a world where there is multiple owner of a Vehicle and A owner can also own multiple Vehicle. You can consider that the Vehicle is used for the rent and one User can rent multiple Vehicle and a Vehicle can be rented by multiple Users.
For Many to Many relationship , we have to annotate in same manner as above with @ManyToMany to collection type data member and for two way binding we have to do the same in the corresponding class. After running the application if we look after the table created by the hibernate , we will found that the there is two mapping table formed one made by first mapping ( by User in this case ) and other mapping table by Vehicle class. So, In order to restrict it, we have to tell hibernate that the mapping is already done by other class with the help of attribute mappedBy in @ManyToMany. So, we will add this attribute in either of the class User or Vehicle.
Vehicle.java
package com.innovatnm.demohibernate.model; import java.util.ArrayList; import java.util.Collection; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToMany; @Entity public class Vehicle { @Id @GeneratedValue(strategy=GenerationType.AUTO) private int id; private String name; @ManyToMany(mappedBy="vehicle") private Collection<User> user=new ArrayList<>();; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Collection<User> getUser() { return user; } public void setUser(Collection<User> user) { this.user = user; } }
Now , After looking upto User class you will got to understand things clearly . So here is User class
User.java
package com.innovatnm.demohibernate.model; import java.util.ArrayList; import java.util.Collection; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.OneToMany; import javax.persistence.OneToOne; import javax.persistence.Table; @Entity @Table(name="user_details") public class User { @GeneratedValue(strategy=GenerationType.AUTO) @Id private int id; private String userName; @ManyToMany(cascade=CascadeType.ALL) @JoinTable(name="usr_vehicle",joinColumns=@JoinColumn(name="user_id"),inverseJoinColumns=@JoinColumn(name="vehicle_id") ) private Collection<Vehicle> vehicle=new ArrayList<>(); @OneToOne(cascade=CascadeType.ALL) @JoinColumn(name="address_id") private Address address; @OneToMany(cascade=CascadeType.ALL) @JoinTable(name="user_mobile_mapping",joinColumns=@JoinColumn(name="user_id"),inverseJoinColumns=@JoinColumn(name="mobile_id")) private Collection<Mobile> mobile=new ArrayList<>();; public Collection<Mobile> getMobile() { return mobile; } public void setMobile(Collection<Mobile> mobile) { this.mobile = mobile; } public Collection<Vehicle> getVehicle() { return vehicle; } public void setVehicle(Collection<Vehicle> vehicle) { this.vehicle = vehicle; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } }
HibernateMain.java
package com.innovatnm.demohibernate; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import com.innovatnm.demohibernate.model.Address; import com.innovatnm.demohibernate.model.Mobile; import com.innovatnm.demohibernate.model.User; import com.innovatnm.demohibernate.model.Vehicle; public class HibernateMain { public static void main(String[] args) { User user=new User(); User user2=new User(); user2.setUserName("Dev"); user.setUserName("Ankit"); Address address= new Address(); address.setStreet("sector 15"); address.setCity("noida"); Address address2=new Address(); address2.setCity("Muzaffarpur"); address2.setStreet("sahebganj"); Vehicle veh=new Vehicle(); veh.setName("car"); Vehicle vehicle=new Vehicle(); vehicle.setName("jeep"); Vehicle vehicle2= new Vehicle(); vehicle2.setName("Bike"); Vehicle vehicle3= new Vehicle(); vehicle3.setName("Bus"); Vehicle vehicle4=new Vehicle(); vehicle4.setName("cycle"); Vehicle vehicle5= new Vehicle(); vehicle5.setName("Truck"); Mobile mobile =new Mobile(); mobile.setBrand("sony"); mobile.setModel("xperia z3"); Mobile mobile2 = new Mobile(); mobile2.setBrand("Redmi"); mobile2.setModel("Note 5 pro"); Mobile mobile3 = new Mobile(); mobile3.setBrand("Nokia"); mobile3.setModel("7 plus"); user.setAddress(address); user2.setAddress(address2); address.setUser(user); address2.setUser(user2); user.getMobile().add(mobile); user.getMobile().add(mobile2); mobile.setUser(user); mobile2.setUser(user); user2.getMobile().add(mobile3); mobile3.setUser(user2); user.getVehicle().add(veh); user.getVehicle().add(vehicle); user.getVehicle().add(vehicle2); veh.getUser().add(user); vehicle.getUser().add(user); vehicle2.getUser().add(user); user2.getVehicle().add(vehicle3); user2.getVehicle().add(vehicle4); user2.getVehicle().add(vehicle5); vehicle3.getUser().add(user2); vehicle4.getUser().add(user2); vehicle5.getUser().add(user2); SessionFactory sf=new Configuration().configure().buildSessionFactory(); Session session=sf.openSession(); session.beginTransaction(); session.save(user); session.save(user2); session.getTransaction().commit(); session.close(); } }
After executing the main class you will found the table as:
address table
mobile table
user_details table
usr_vehicle table
user_mobile_mapping table
vehicle table