How to use Association Mapping in Hibernate?

In the previous article, we have seen How to Map Collection in Hibernate? You can check it here How to Map Collection in Hibernate? In this article, we will see What is Association Mapping?

You must have noticed in the previous article we have use elements such as <one-to-many>. This element signifies the relationship between the database table and model.

What is Association Mapping in Hibernate?

The association mapping defines the relationship between the table and the entity class. There can be a unidirectional or bidirectional association between them, that we need to define in the Mapping file. So, we have the following relationship that can be established-

  • one-to-one mapping
  • many-to-one mapping
  • one-to-many mapping

What is one to one mapping in Hibernate?

This mapping represents a one-to-one relationship between two tables. We will understand this in detail by considering a scenario where a customer has a unique account number.

Create a database and table

<-------Create Database--------->
mysql>create database bank;
<-------Use database------------>
mysql>use bank;
<------create table customer_table---->
mysql>CREATE TABLE `customer_table` (
  `cust_id` int NOT NULL AUTO_INCREMENT,
  `cust_name` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`cust_id`)
);
<------create child table account_table--->
mysql>CREATE TABLE `account_table` (
  `acc_id` int NOT NULL,
  `acc_no` int DEFAULT NULL,
  PRIMARY KEY (`acc_id`),
  CONSTRAINT `account_table_ibfk_1` FOREIGN KEY (`acc_id`) REFERENCES `customer_table` (`cust_id`)
) ;

Create a persistent class-Customer.java

public class Customer {

  private int cust_id;
  private String cust_name;
  private Account account;

  public int getCust_id() {
    return cust_id;
  }

  public void setCust_id(int cust_id) {
    this.cust_id = cust_id;
  }

  public String getCust_name() {
    return cust_name;
  }

  public void setCust_name(String cust_name) {
    this.cust_name = cust_name;
  }

  public Account getAccount() {
    return account;
  }

  public void setAccount(Account account) {
    this.account = account;
  }

}

Account.java

public class Account {

  private int acc_id;
  private int acc_no;
  private Customer customer;

  public Customer getCustomer() {
    return customer;
  }

  public void setCustomer(Customer customer) {
    this.customer = customer;
  }

  public int getAcc_id() {
    return acc_id;
  }

  public void setAcc_id(int acc_id) {
    this.acc_id = acc_id;
  }

  public int getAcc_no() {
    return acc_no;
  }

  public void setAcc_no(int acc_no) {
    this.acc_no = acc_no;
  }

}

Create hibernate.cfg.xml file

<?xml version='1.0' encoding='UTF-8'?>  
<!DOCTYPE hibernate-configuration PUBLIC  
          "-//Hibernate/Hibernate Configuration DTD 5.3//EN"  
          "http://hibernate.sourceforge.net/hibernate-configuration-5.3.dtd">

<hibernate-configuration>

  <session-factory>
    <property name="hbm2ddl.auto">update</property>
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="connection.url">jdbc:mysql://localhost:3306/bank</property>
    <property name="connection.username">root</property>
    <property name="connection.password">khan</property>
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    <mapping resource="customer.hbm.xml" />
    <mapping resource="account.hbm.xml" />
  </session-factory>

</hibernate-configuration>

Create mapping file-customer.hbm.xml and account.hbm.xml

  • As we know, we can have as many mapping files. So, I have created a separate mapping file for the Customer and account.
  • <cust_id> which is the primary key in customer_table is a foreign key in account table for that I have used generator class as foreign in account.hbm.xml.
  • I have shown the relationship using <one-to-one > element.
  • The cascade attribute used here is mandatory if we want to show the relationship between objects. The <cascade=”all”> implies that if any changes occur at the parent table then it should be reflected in the child table and vice-versa.
<?xml version='1.0' encoding='UTF-8'?>  
<!DOCTYPE hibernate-mapping PUBLIC  
          "-//Hibernate/Hibernate Mapping DTD 5.3//EN"  
          "http://hibernate.sourceforge.net/hibernate-mapping-5.3.dtd">
<hibernate-mapping>
  <class name="Customer" table="customer_table">
    <id name="cust_id">
      <generator class="increment" />
    </id>
    <property name="cust_name" />


    <one-to-one name="account" cascade="all" />
  </class>

</hibernate-mapping>

account.hbm.xml

<!DOCTYPE hibernate-mapping PUBLIC  
          "-//Hibernate/Hibernate Mapping DTD 5.3//EN"  
          "http://hibernate.sourceforge.net/hibernate-mapping-5.3.dtd">
<hibernate-mapping>
  <class name="Account" table="account_table">
    <id name="acc_id">
      <generator class="foreign">
        <param name="property">customer</param>
      </generator>
    </id>
    <property name="acc_no" />

    <one-to-one name="customer" />
  </class>

</hibernate-mapping>

TestClass.java

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class TestClass {

  public static void main(String[] args) {
    // TODO Auto-generated method stub
    Customer customer = new Customer();
    customer.setCust_name("ABC");
    Account account = new Account();
    account.setAcc_no(786);
    customer.setAccount(account);
    account.setCustomer(customer);
    SessionFactory factory = new Configuration().configure().buildSessionFactory();
    Session session = factory.openSession();
    session.beginTransaction();
    session.persist(account);
    session.getTransaction().commit();
    System.out.println("added");

  }

}

Output

Database changed
mysql> select * from customer_table;
+---------+-----------+
| cust_id | cust_name |
+---------+-----------+
|       1 | ABC       |
+---------+-----------+
1 row in set (0.00 sec)

mysql> select * from account_table;
+--------+--------+
| acc_id | acc_no |
+--------+--------+
|      1 |    786 |
+--------+--------+
1 row in set (0.00 sec)

Thus this is How one-to-one mapping is done in Hibernate.

What is many to one mapping in Hibernate?

This mapping represents the mapping relationship between many tables to one table. We will understand this in detail by considering a scenario many Players are in one Team.

Create a database and table

<-------Create database and Table------->
mysql>create database player;
<--------use database------------------->
mysql>use player;
<--------Create table player_table------>
mysql>CREATE TABLE `player_table` (
  `pid` int NOT NULL AUTO_INCREMENT,
  `pname` varchar(45) DEFAULT NULL,
  `psalary` int DEFAULT NULL,
  `team` int DEFAULT NULL,
  PRIMARY KEY (`pid`),
  KEY `FKa73vgjsaewpd08meb4sofmxmq` (`team`),
  CONSTRAINT `FKa73vgjsaewpd08meb4sofmxmq` FOREIGN KEY (`team`) REFERENCES `team_table` (`tid`)
) ;
<------Create table team_table---------->
mysql>CREATE TABLE `team_table` (
  `tid` int NOT NULL,
  `tname` varchar(45) DEFAULT NULL,
  `tcountry` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`tid`)
);

Create a persistent class-Player.java

public class Player {

  private int pid;
  private String pname;
  private int psalary;
  private Team team;

  public Player() {
    super();
    // TODO Auto-generated constructor stub
  }

  public Player(String pname, int psalary, Team team) {
    super();
    this.pname = pname;
    this.psalary = psalary;
    this.team = team;
  }

  public Team getTeam() {
    return team;
  }

  public void setTeam(Team team) {
    this.team = team;
  }

  public int getPid() {
    return pid;
  }

  public void setPid(int pid) {
    this.pid = pid;
  }

  public String getPname() {
    return pname;
  }

  public void setPname(String pname) {
    this.pname = pname;
  }

  public int getPsalary() {
    return psalary;
  }

  public void setPsalary(int psalary) {
    this.psalary = psalary;
  }

}

Team.java

public class Team {

  private int tid;
  private String tname;
  private String tcountry;
  private Player player;

  public Player getPlayer() {
    return player;
  }

  public void setPlayer(Player player) {
    this.player = player;
  }

  public Team() {
    super();
    // TODO Auto-generated constructor stub
  }

  public Team(int tid, String tname, String tcountry) {
    super();
    this.tid = tid;
    this.tname = tname;
    this.tcountry = tcountry;
  }

  public Team(String tname, String tcountry) {
    super();
    this.tname = tname;
    this.tcountry = tcountry;
  }

  public int getTid() {
    return tid;
  }

  public void setTid(int tid) {
    this.tid = tid;
  }

  public String getTname() {
    return tname;
  }

  public void setTname(String tname) {
    this.tname = tname;
  }

  public String getTcountry() {
    return tcountry;
  }

  public void setTcountry(String tcountry) {
    this.tcountry = tcountry;
  }

}

hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?>  
<!DOCTYPE hibernate-configuration PUBLIC  
          "-//Hibernate/Hibernate Configuration DTD 5.3//EN"  
          "http://hibernate.sourceforge.net/hibernate-configuration-5.3.dtd">

<hibernate-configuration>

  <session-factory>
    <property name="hbm2ddl.auto">update</property>
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="connection.url">jdbc:mysql://localhost:3306/player</property>
    <property name="connection.username">root</property>
    <property name="connection.password">root</property>
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    <mapping resource="player.hbm.xml" />

  </session-factory>

</hibernate-configuration>

player.hbm.xml file

  • In this, I have used the <many-to-one> element to show the relationship between Players and the team.
  • The cascade attribute used here is mandatory if we want to show the relationship between objects. The <cascade=”all”> implies that if any changes occur at the parent table then it should be reflected in the child table and vice-versa.
<?xml version='1.0' encoding='UTF-8'?>  
<!DOCTYPE hibernate-mapping PUBLIC  
          "-//Hibernate/Hibernate Mapping DTD 5.3//EN"  
          "http://hibernate.sourceforge.net/hibernate-mapping-5.3.dtd">
<hibernate-mapping>
  <class name="Player" table="player_table">
    <id name="pid" type="int" column="pid">
      <generator class="increment" />
    </id>
    <property name="pname" column="pname" type="string" />
    <property name="psalary" column="psalary" type="int" />
    <many-to-one name="team" cascade="all" />
  </class>

  <class name="Team" table="team_table">



    <id name="tid" type="int" column="tid">
      <generator class="increment" />
    </id>

    <property name="tname" column="tname" type="string" />
    <property name="tcountry" column="tcountry" type="string" />

  </class>

</hibernate-mapping>

TestClass.java

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class TestClass {

  public static void main(String[] args) {
    // TODO Auto-generated method stub
    Player player = new Player();
    player.setPname("Rahul dravid");
    player.setPsalary(7860);
    Player player2 = new Player();

    player2.setPname("Saurav Ganguly");
    player2.setPsalary(8950);
    Team team = new Team();
    team.setTname("Indian Cricket Team");
    team.setTcountry("India");
    player.setTeam(team);
    player2.setTeam(team);

    SessionFactory factory = new Configuration().configure().buildSessionFactory();
    Session session = factory.openSession();
    session.beginTransaction();
    session.persist(player);
    session.persist(player2);
    System.out.println("added");
    session.getTransaction().commit();
  }

}

Output

mysql> select * from player_table;
+-----+----------------+---------+------+
| pid | pname          | psalary | team |
+-----+----------------+---------+------+
|   1 | Rahul dravid   |    7860 |    1 |
|   2 | Rahul dravid   |    7860 |    2 |
|   3 | Saurav Ganguly |    8950 |    2 |
+-----+----------------+---------+------+
3 rows in set (0.60 sec)

mysql> select * from team_table;
+-----+---------------------+----------+
| tid | tname               | tcountry |
+-----+---------------------+----------+
|   1 | Indian Cricket Team | India    |
|   2 | Indian Cricket Team | India    |
+-----+---------------------+----------+
2 rows in set (0.78 sec)

Thus this is how many to one Hibernate in mapping.

What is one to many mapping in Hibernate?

It represents the relationship between one and many objects such as One student can have many degrees.

Note: For one-to-many example, refer to the Set article example How to Map Collection in Hibernate? where I have used the one-to-many relationship between Student and degree.

Thus this article was all about association mapping in Hibernate.

In the next article of this tutorial, we will cover Annotation in Hibernate with a simple example.