Hibernate Bidirectional Mapping Example with @JoinTable Annotation
February 22, 2015
In this page, we will learn hibernate bidirectional mapping example with @JoinTable annotation. Bidirectional mapping means two entities are associated in a way that one can be fetched from another entity. @JoinTable annotation joins the associating table with the help of third table. In our example for bidirectional mapping OneToMany/OneToOne association is being used.
@JoinTable
@JoinTable annotation is used to join two table using a third table. This third table associates two table by their Ids. To define @JoinTable we can use below attributes.name: This is the name of third table.
joinColumns: Assign the column of third table related to entity itself.
inverseJoinColumns: Assign the column of third table related to associated entity.
Look at the below code snippet.
@Entity @Table(name="company") public class Company { ----------------------------------------------------- ----------------------------------------------------- @OneToMany(cascade=CascadeType.ALL) @JoinTable(name="Company_Employee", joinColumns={@JoinColumn(name ="companyId", referencedColumnName ="id")}, inverseJoinColumns={@JoinColumn(name ="employeeId", referencedColumnName ="id")}) private Set<Employee> employees; ----------------------------------------------------- ----------------------------------------------------- } @Entity @Table(name="employee") public class Employee { ----------------------- ----------------------- @OneToOne(cascade=CascadeType.ALL) @JoinTable(name="Company_Employee", joinColumns={@JoinColumn(name ="employeeId", referencedColumnName ="id")}, inverseJoinColumns={@JoinColumn(name ="companyId", referencedColumnName ="id")}) private Company company; ----------------------- ----------------------- }
Database Structure
Find database schema and the relationship between the tables as below. In the third table, there is two column for the id of both table.Create An Entity Using @OneToMany
Find the entity which is using @OneToMany mapping with @JoinTable.Company.java
package com.concretepage; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.OneToMany; import javax.persistence.Table; @Entity @Table(name="company") public class Company { @Id @Column(name="id") private Integer id; @Column(name="name") private String name; @OneToMany(cascade=CascadeType.ALL) @JoinTable(name="Company_Employee", joinColumns={@JoinColumn(name ="companyId", referencedColumnName ="id")}, inverseJoinColumns={@JoinColumn(name ="employeeId", referencedColumnName ="id")}) private Set<Employee> employees; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set<Employee> getEmployees() { return employees; } public void setEmployees(Set<Employee> employees) { this.employees = employees; } }
Create An Entity Using @OneToOne
Find the entity which is using @OneToOne mapping with @JoinTable.Employee.java
package com.concretepage; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.OneToOne; import javax.persistence.Table; @Entity @Table(name="employee") public class Employee { @Id @Column(name="id") private Integer id; @Column(name="name") private String name; @OneToOne(cascade=CascadeType.ALL) @JoinTable(name="Company_Employee", joinColumns={@JoinColumn(name ="employeeId", referencedColumnName ="id")}, inverseJoinColumns={@JoinColumn(name ="companyId", referencedColumnName ="id")}) private Company company; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Company getCompany() { return company; } public void setCompany(Company company) { this.company = company; } }
hibernate.cfg.xml
Find the hibernate.cfg.xml file.hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url"> jdbc:mysql://localhost:3306/concretepage</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password"></property> <property name="hibernate.connection.pool_size">10</property> <property name="show_sql">true</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.hbm2ddl.auto">update</property> <mapping class="com.concretepage.Company"/> <mapping class="com.concretepage.Employee"/> </session-factory> </hibernate-configuration>
Hibernate Utility Class
Find the hibernate utility class.HibernateUtil.java
package com.concretepage; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static SessionFactory sessionFactory ; static { Configuration configuration = new Configuration().configure(); StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()); sessionFactory = configuration.buildSessionFactory(builder.build()); } public static SessionFactory getSessionFactory() { return sessionFactory; } }
Main Class to Test Bidirectional Mapping
Now run the example to test the bidirectional mapping.JoinTableDemo.java
package com.concretepage; import java.util.Set; import org.hibernate.Session; public class JoinTableDemo { public static void main(String[] args) { Session session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); System.out.println("---Fetch Employess---"); Company company = (Company) session.get(Company.class, new Integer(1)); Set<Employee> employees = company.getEmployees(); for(Employee e: employees){ System.out.println("Id:"+e.getId()+", Name:"+e.getName()); } System.out.println("---Fetch Company---"); Employee emp = (Employee) session.get(Employee.class, new Integer(2)); System.out.println("Name:"+emp.getName()+", Company Name:"+ emp.getCompany().getName()); session.close(); } }
---Fetch Employess--- Hibernate: select company0_.id as id1_1_0_, company0_.name as name2_1_0_ from company company0_ where company0_.id=? Hibernate: select employees0_.companyId as companyI1_1_0_, employees0_.employeeId as employee2_0_0_, employee1_.id as id1_2_1_, employee1_.name as name2_2_1_, employee1_1_.companyId as companyI1_0_1_ from Company_Employee employees0_ inner join employee employee1_ on employees0_.employeeId=employee1_.id left outer join Company_Employee employee1_1_ on employee1_.id=employee1_1_.employeeId where employees0_.companyId=? Id:1, Name:A Id:2, Name:B Id:4, Name:D ---Fetch Company--- Name:B, Company Name:ABC