Hibernate many-to-one bidirectional mapping using annotation

Hi friends,

It’s all about hibernate many-to-one bidirectional mapping. Here we can discuss about country – continent relationship. That is, many countries lies in one continent. Okay, let’s start.

The DAO class, DAO.java

package hba.dao;

import hba.util.HibernateUtil;
import org.hibernate.FlushMode;
import org.hibernate.Session;

public class DAO {

    private static final ThreadLocal THREAD = new ThreadLocal();

    protected DAO() {
    }

    public static Session getSession() {
        Session session = (Session) DAO.THREAD.get();
        if (session == null) {
            session = HibernateUtil.getSessionFactory().openSession();
            DAO.THREAD.set(session);
            getSession().setFlushMode(FlushMode.COMMIT);
        }
        return session;
    }

    protected static void begin() {
        getSession().beginTransaction();
    }

    protected static void commit() {
        getSession().getTransaction().commit();
    }

    protected static void rollback() {
        getSession().getTransaction().rollback();
        getSession().close();
        DAO.THREAD.set(null);
    }

    protected static void flush() {
        getSession().flush();
    }

    protected static void close() {
        getSession().close();
        DAO.THREAD.set(null);
    }
}

The configuration file, hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!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="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hba</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">password1.</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>
        <mapping class="hba.pojo.m2o_b_continent"/>
        <mapping class="hba.pojo.m2o_b_country"/>
    </session-factory>
</hibernate-configuration>

Here’s my country POJO, m2o_b_country.java

package hba.pojo;

import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "COUNTRY", catalog = "hba")
public class m2o_b_country implements Serializable {

    private long ctry_code;
    private String ctry_name;
    private m2o_b_continent continent = new m2o_b_continent();

    @Id
    @Column(name = "CODE", length = 20)
    public long getCtry_code() {
        return ctry_code;
    }

    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    public m2o_b_continent getContinent() {
        return continent;
    }

    @Column(name = "NAME", length = 20)
    public String getCtry_name() {
        return ctry_name;
    }

    public void setContinent(m2o_b_continent continent) {
        this.continent = continent;
    }

    public void setCtry_code(long ctry_code) {
        this.ctry_code = ctry_code;
    }

    public void setCtry_name(String ctry_name) {
        this.ctry_name = ctry_name;
    }
}

The continent POJO, m2o_b_continent.java

package hba.pojo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = "CONTINENT", catalog = "hba")
public class m2o_b_continent implements Serializable {

    private long cnt_code;
    private String cnt_name;
    private List<m2o_b_country> countries = new ArrayList<m2o_b_country>();

    @Column(name = "NAME", length = 20)
    public String getCnt_name() {
        return cnt_name;
    }

    @Id
    @Column(name = "CODE", length = 10)
    public long getCnt_code() {
        return cnt_code;
    }

    @OneToMany(mappedBy = "continent", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    public List<m2o_b_country> getCountries() {
        return countries;
    }

    public void setCnt_code(long cnt_code) {
        this.cnt_code = cnt_code;
    }

    public void setCnt_name(String cnt_name) {
        this.cnt_name = cnt_name;
    }

    public void setCountries(List<m2o_b_country> countries) {
        this.countries = countries;
    }

    public void addCountry(m2o_b_country country) {
        country.setContinent(this);
        countries.add(country);
    }

    public m2o_b_continent(long cnt_code) {
        this.cnt_code = cnt_code;
    }

    public m2o_b_continent() {
    }
}

This is how we gonna persist both entities, the save() method of m2o_b_country_continent.java.

package hba.biz;

import hba.dao.DAO;
import hba.pojo.m2o_b_country;
import hba.pojo.m2o_b_continent;
import java.util.ArrayList;
import java.util.List;

public class m2o_b_country_continent extends DAO {

    m2o_b_country country1 = new m2o_b_country();
    m2o_b_country country2 = new m2o_b_country();
    m2o_b_continent continent = new m2o_b_continent();
    List<m2o_b_country> countries = new ArrayList<m2o_b_country>();

    public void save() {
        try {
            begin();
            continent.setCnt_code(1);
            continent.setCnt_name("ASIA");
            country1.setCtry_code(127);
            country1.setCtry_name("INDIA");
            country1.setContinent(continent);
            country2.setCtry_code(128);
            country2.setCtry_name("JAPAN");
            country2.setContinent(continent);
            countries.add(country1);
            countries.add(country2);
            continent.setCountries(countries);
            getSession().save(country1);
            getSession().save(country2);
            commit();
        } catch (Exception e) {
            rollback();
            System.out.println("Exception : " + e.getMessage() + "Cause : " + e.getCause());
        } finally {
            flush();
            close();
        }
    }

    public static void main(String[] args) {
        try {
            m2o_b_country_continent cc = new m2o_b_country_continent();
            cc.save();
        } catch (Exception e) {
            System.out.println("Exception : " + e.getMessage() + "Cause : " + e.getCause());
        }
    }
}

The above save() method outputs.

Hibernate: select m2o_b_cont_.CODE, m2o_b_cont_.NAME as NAME12_ from hba.CONTINENT m2o_b_cont_ where m2o_b_cont_.CODE=?
Hibernate: select m2o_b_coun_.CODE, m2o_b_coun_.continent_CODE as continent3_13_, m2o_b_coun_.NAME as NAME13_ from hba.COUNTRY m2o_b_coun_ where m2o_b_coun_.CODE=?
Hibernate: insert into hba.CONTINENT (NAME, CODE) values (?, ?)
Hibernate: insert into hba.COUNTRY (continent_CODE, NAME, CODE) values (?, ?, ?)
Hibernate: insert into hba.COUNTRY (continent_CODE, NAME, CODE) values (?, ?, ?)

Here, we have created two countries and one continent. We have set both countries to the continent and set the continent of each country as the above continent object.

Now, the list of countries, listCountry() method.

package hba.biz;

import hba.dao.DAO;
import hba.pojo.m2o_b_country;
import hba.pojo.m2o_b_continent;
import java.util.ArrayList;
import java.util.List;

public class m2o_b_country_continent extends DAO {

    m2o_b_country country1 = new m2o_b_country();
    m2o_b_country country2 = new m2o_b_country();
    m2o_b_continent continent = new m2o_b_continent();
    List<m2o_b_country> countries = new ArrayList<m2o_b_country>();

    public void listCountry() {
        try {
            begin();
            List<m2o_b_country> Countries = getSession().createQuery("from m2o_b_country").list();
            for (m2o_b_country Country : Countries) {
                System.out.println("Country Code : " + Country.getCtry_code());
                System.out.println("Country Name : " + Country.getCtry_name());
                System.out.println("Continent Name : " + Country.getContinent().getCnt_name());
            }
            commit();
        } catch (Exception e) {
            rollback();
            System.out.println("Exception : " + e.getMessage() + "Cause : " + e.getCause());
        } finally {
            flush();
            close();
        }
    }

    public static void main(String[] args) {
        try {
            m2o_b_country_continent cc = new m2o_b_country_continent();
            cc.listCountry();
        } catch (Exception e) {
            System.out.println("Exception : " + e.getMessage() + "Cause : " + e.getCause());
        }
    }
}

It outputs.

Hibernate: select m2o_b_coun0_.CODE as CODE13_, m2o_b_coun0_.continent_CODE as continent3_13_, m2o_b_coun0_.NAME as NAME13_ from hba.COUNTRY m2o_b_coun0_
Country Code : 127
Country Name : INDIA
Hibernate: select m2o_b_cont0_.CODE as CODE12_0_, m2o_b_cont0_.NAME as NAME12_0_ from hba.CONTINENT m2o_b_cont0_ where m2o_b_cont0_.CODE=?
Continent Name : ASIA
Country Code : 128
Country Name : JAPAN
Continent Name : ASIA

Now, the list of continents with its countries, listContinent() method.

package hba.biz;

import hba.dao.DAO;
import hba.pojo.m2o_b_country;
import hba.pojo.m2o_b_continent;
import java.util.ArrayList;
import java.util.List;

public class m2o_b_country_continent extends DAO {

    m2o_b_country country1 = new m2o_b_country();
    m2o_b_country country2 = new m2o_b_country();
    m2o_b_continent continent = new m2o_b_continent();
    List<m2o_b_country> countries = new ArrayList<m2o_b_country>();

       public void listContinent() {
        try {
            begin();
            List<m2o_b_continent> Continents = getSession().createQuery("from m2o_b_continent").list();
            for (m2o_b_continent Continent : Continents) {
                System.out.println("Continent Name : " + Continent.getCnt_name());
                List<m2o_b_country> Countries = Continent.getCountries();
                for (m2o_b_country Country : Countries) {
                    System.out.println("Country Code : " + Country.getCtry_code());
                    System.out.println("Country Name : " + Country.getCtry_name());
                }
            }
            commit();
        } catch (Exception e) {
            rollback();
            System.out.println("Exception : " + e.getMessage() + "Cause : " + e.getCause());
        } finally {
            flush();
            close();
        }
    }

    public static void main(String[] args) {
        try {
            m2o_b_country_continent cc = new m2o_b_country_continent();
            cc.listContinent();
        } catch (Exception e) {
            System.out.println("Exception : " + e.getMessage() + "Cause : " + e.getCause());
        }
    }
}

And, the output will be…

Hibernate: select m2o_b_cont0_.CODE as CODE12_, m2o_b_cont0_.NAME as NAME12_ from hba.CONTINENT m2o_b_cont0_ where m2o_b_cont0_.CODE=1252
Continent Name : ASIA
Hibernate: select countries0_.continent_CODE as continent3_1_, countries0_.CODE as CODE1_, countries0_.CODE as CODE13_0_, countries0_.continent_CODE as continent3_13_0_, countries0_.NAME as NAME13_0_ from hba.COUNTRY countries0_ where countries0_.continent_CODE=?
Country Code : 127
Country Name : INDIA
Country Code : 128
Country Name : JAPAN

Thanks.

Hibernate many-to-one unidirectional mapping using annotation

Hi friends,

Now let’s discuss hibernate many-to-one unidirectional mapping. As the name says, unidirectional mapping starts from parent entity and ends at child entity. Here, we are about to discuss many-to-one mapping. A many-to-one mapping simply equivalent to a one-to-one mapping, which we have already discussed. Click here for one-to-one unidirectional mapping and here for one-to-one bidirectional mapping. The only difference between one-to-one and many-to-one is, in former one, a parent can have exactly one child, but in latter, many parents can have the same child.

As usual, let’s start from DAO class, DAO.java.

package hba.dao;

import hba.util.HibernateUtil;
import org.hibernate.FlushMode;
import org.hibernate.Session;

public class DAO {

    private static final ThreadLocal THREAD = new ThreadLocal();

    protected DAO() {
    }

    public static Session getSession() {
        Session session = (Session) DAO.THREAD.get();
        if (session == null) {
            session = HibernateUtil.getSessionFactory().openSession();
            DAO.THREAD.set(session);
            getSession().setFlushMode(FlushMode.COMMIT);
        }
        return session;
    }

    protected static void begin() {
        getSession().beginTransaction();
    }

    protected static void commit() {
        getSession().getTransaction().commit();
    }

    protected static void rollback() {
        getSession().getTransaction().rollback();
        getSession().close();
        DAO.THREAD.set(null);
    }

    protected static void flush() {
        getSession().flush();
    }

    protected static void close() {
        getSession().close();
        DAO.THREAD.set(null);
    }
}

The configuration file, hibernate.cfg.xml.

<?xml version="1.0" encoding="UTF-8"?>
<!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="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hba</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">password</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>
        <mapping class="hba.pojo.m2o_u_employee"/>
        <mapping class="hba.pojo.m2o_u_job"/>
    </session-factory>
</hibernate-configuration>

Here, I tell you the relationship between employee and job. Even though just a job entity in real world will not exist and will not be mapped into a relational database, I assume that it could help us for learning the concept. The relationship is, many employees can have the same job. This is true in real case.

The employee POJO, m2o_u_employee.java.

package hba.pojo;

import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "EMPLOYEE", catalog = "hba")
public class m2o_u_employee implements Serializable {

    private long emp_id;
    private String emp_name;
    private m2o_u_job job = new m2o_u_job();

    @Id
    @GeneratedValue
    @Column(name = "EMP_ID")
    public long getEmp_id() {
        return emp_id;
    }

    @Column(name = "EMP_NAME", length = 20)
    public String getEmp_name() {
        return emp_name;
    }

    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    public m2o_u_job getJob() {
        return job;
    }

    public void setEmp_id(long emp_id) {
        this.emp_id = emp_id;
    }

    public void setEmp_name(String emp_name) {
        this.emp_name = emp_name;
    }

    public void setJob(m2o_u_job job) {
        this.job = job;
    }
}

The job POJO, m2o_u_job.java.

package hba.pojo;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "JOB", catalog = "hba")
public class m2o_u_job implements Serializable {

    private long job_id;
    private String job_name;

    @Id
    @GeneratedValue
    @Column(name = "JOB_ID")
    public long getJob_id() {
        return job_id;
    }

    @Column(name = "JOB_NAME", length = 20)
    public String getJob_name() {
        return job_name;
    }

    public void setJob_id(long job_id) {
        this.job_id = job_id;
    }

    public void setJob_name(String job_name) {
        this.job_name = job_name;
    }
}

This is how we persist both entities and follow out a mapping between them, the save() method of m2o_u_emp_job.java class.

package hba.biz;

import hba.dao.DAO;
import hba.pojo.m2o_u_employee;
import hba.pojo.m2o_u_job;

public class m2o_u_emp_job extends DAO {

    public void save() {
        try {
            begin();
            m2o_u_employee emp1 = new m2o_u_employee();
            m2o_u_employee emp2 = new m2o_u_employee();
            m2o_u_job job = new m2o_u_job();
            job.setJob_name("CEO");
            emp1.setEmp_name("John");
            emp2.setEmp_name("Sandeep");
            emp1.setJob(job);
            emp2.setJob(job);
            getSession().save(emp1);
            getSession().save(emp2);
            commit();
        } catch (Exception e) {
            rollback();
            System.out.println("Exception : " + e.getMessage() + "Cause : " + e.getCause());
        } finally {
            flush();
            close();
        }
    }

    public static void main(String[] args) throws Exception {
        new m2o_u_emp_job().save();
    }
}

This will be the output of above save() method.

Hibernate: insert into hba.JOB (JOB_NAME) values (?)
Hibernate: insert into hba.EMPLOYEE (EMP_NAME, job_JOB_ID) values (?, ?)
Hibernate: insert into hba.EMPLOYEE (EMP_NAME, job_JOB_ID) values (?, ?)

What happens here is, we are creating two employee objects and a job object, assigning each employee’s job as the new job object, then persisting both employee objects and the job object.

Thanks.