22 Dec 2014

One-To-One Mapping in Hibernate Using Annotation

One-To-One Mapping: One-To-One mapping is almost same as Many-To-One mapping except that only one instance of source entity can refer to one target entity instance. In other words a target entity instance is shared among not more than one source entity instance.

A realistic example of a One-To-One mapping is the relation between a Country and its Capital that each country has only one capital. The following figure clearly implies the One-To-One relationship between Country and Capital.


Here, Country is as the source in the relationship and Capital as the target. And, the arrow points only in one direction from Country to Capital which means the relationship is unidirectional. We can discuss about bidirectional One-To-One mapping later. Now let us see the step by step procedure for One-To-One mapping with this example by creating a simple java project in Eclipse.
Here, in this example we will use PostgreSQL database.

1. Create a new Java Project 

In Eclipse, Create a new Java Project 'Hiberate_App'.

2. Updating Build Path

In order to use Hibernate in our project we have to update Java Build Path as shown in screenshot:

     - Right click on project and select properties.

 - Select Java Build Path(1) and then Libraries(2).
     - Click on Add External Jars(3) and select all required jar files to run a project using Hibernate and click           Ok(4). We have updated the build path for our project to use Hibernate.

3. Creating Model Classes

In project explorer, right click on src folder and create a package with name javakart in which we will create all our .java files of our project.

Create two classes Country.java and Capital.java inside javakart package as shown below:

Country.java
package javakart;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.JoinColumn;
import javax.persistence.Table;

@Entity
@Table(name="COUNTRY")
public class Country{
 
 @Id
 @Column(name="country_id")
 private Integer countryId;
 
 @Column(name="name")
 private String name;
 
 @OneToOne
 @JoinColumn(name="cap_id")
 private Capital capital

 // Getters and Setters
 public Integer getCountryId() {
  return countryId;
 }
 public void setCountryId(Integer countryId) {
  this.countryId = countryId;
 }

 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }

 public Capital getCapital() {
  return capital;
 }
 public void setCapital(Capital capital) {
  this.capital = capital;
 }

}

In Country.java, define One-To-One mapping by using @OneToOne annotation on the capital attribute.
And, @JoinColumn is used to specify the name of the foreign key column that refers to a key in another table. Here, we are giving foreign key column name as 'cap_id' by using @JoinColumn(name="cap_id"). If we didn't specify @JoinColumn then a default name is formed from a combination of source & target entities which is 'name of the relationship attribute in source entity' plus 'underscore' plus 'name of the primary key column of  target entity'. Thus, the default name formed to foreign key column is 'capital_capital_id'. But, in database if this is not the actual column name which already exists then @JoinColumn annotation must be defined to override the default. In our example we override the default join column name to be cap_id.

Capital.java
package javakart;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="CAPITAL")
public class Capital{

 @Id
 @Column(name="capital_id")
 private Integer capitalId;

 @Column(name="name")
 private String name;

 // Getters and Setters
 public Integer getCapitalId() {
  return capitalId;
 }
 public void setCapitalId(Integer capitalId) {
  this.capitalId = capitalId;
 }

 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 
}

4. Create HibernateUtil.java and Main.java for accessing data to & from database

HibernateUtil.java
package javakart;

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

public class HibernateUtil {

    private static final SessionFactory sf = buildSessionFactory();

    @SuppressWarnings("deprecation")
 private static SessionFactory buildSessionFactory() {
        try {
            return new Configuration().configure().buildSessionFactory();
        }
        catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static Session openSession() {
        return sf.openSession();
    }

}

Main.java
package javakart;

import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class Main{

 public static void main(String[] args){

  // Add Country Details
  Capital cap1 = new Capital();
  cap1.setCapitalId(1);
  cap1.setName("New Delhi");
  
  Capital cap2 = new Capital();
  cap2.setCapitalId(2);
  cap2.setName("Jakarta");
  
  // Add Countries
  Country country1 = new Country();
  country1.setCountryId(1);
  country1.setName("India");
  country1.setCapital(cap1);
  
  Country country2 = new Country();
  country2.setCountryId(2);
  country2.setName("Indonesia");
  country2.setCapital(cap2);
  
  
  try{
   Session s = HibernateUtil.openSession();
   Transaction tx = s.beginTransaction();
   
   s.save(cap1);
   s.save(cap2);
   s.save(country1);
   s.save(country2);
   tx.commit();
   s.flush();
   s.close();
  }catch(Exception ex){
   System.out.println("Error while adding: "+ex.getMessage());
  }
  //---- End ----
  
  // Reading Country Details
  try{
   Session s = HibernateUtil.openSession();
   s.beginTransaction();
   
   Query query = s.createQuery("from Country");
   List list = query.list();
   System.out.println("Country \t Capital");
   for(Country country:list){
    System.out.print(country.getName());
    System.out.print("\t");
    System.out.println(country.getCapital().getName());
    
   }
  }catch(Exception ex){
   System.out.println("Error while reading: "+ex.getMessage());
  }
  // ---- End ----
  
 }

}
5. Configure Hibernate Configuration File

Inside src folder, create a hibernate.cfg.xml file and update it as shown below:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="connection.driver_class">org.postgresql.Driver</property>
    <property name="connection.url">jdbc:postgresql://localhost/
                                   Hibernate_Practice</property>
    <property name="connection.username">postgres</property>
    <property name="connection.password">mypassword</property>
    <property name="connection.pool_size">10</property>
    <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
    <property name="current_session_context_class">thread</property>
    <property name="cache.provider_class">org.hibernate.cache.internal
                                            .NoCacheProvider</property>
    <property name="show_sql">true</property>
    <property name="hbm2ddl.auto">update</property>
    
    <mapping class="javakart.Country"/>
    <mapping class="javakart.Capital"/>
  </session-factory>

</hibernate-configuration>

6. Finally, our project structure will looks as shown in screenshot:

7. Try to run Main.java. In console we will find the output as:
Hibernate: insert into CAPITAL (name, capital_id) values (?, ?)
Hibernate: insert into CAPITAL (name, capital_id) values (?, ?)
Hibernate: insert into COUNTRY (capital_capital_id, name, population, country_id)
values (?, ?, ?, ?)
Hibernate: insert into COUNTRY (capital_capital_id, name, population, country_id)
values (?, ?, ?, ?)
Hibernate: select country0_.country_id as country_1_1_,
country0_.capital_capital_id as capital_4_1_, country0_.name as name2_1_,
country0_.population as populati3_1_ from COUNTRY country0_
Hibernate: select capital0_.capital_id as capital_1_0_0_, capital0_.name as
name2_0_0_ from CAPITAL capital0_ where capital0_.capital_id=?
Hibernate: select capital0_.capital_id as capital_1_0_0_, capital0_.name as
name2_0_0_ from CAPITAL capital0_ where capital0_.capital_id=?

Country    Capital
John          New Delhi
Indonesia   Jakarta

In database, we will find Employee & Department tables as:






Popular Posts

Write to Us
Name
Email
Message