Home >> Hibernate
Example on setting up a one to one mapping between two Entities
using Hibernate as persistence ORM tool
Example case study:
Car and Registration number are basically related to each other as
one two one, that means for a single car, there could be at most
a single registration number, and vice versa.
so basically there is a one to one mapping between car and registration
number for this car. We have two POJO defined, one is Car and the other
one is RegistrationDetails, as follows:
This is just an example domain class from this Page case study.
Car.java
package example;
public class Car {
private String carName;
private String model;
private String segment;
private RegistrationDetails registrationDetails;
public String getCarName() {
return carName;
}
public void setCarName(String carName) {
this.carName = carName;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public RegistrationDetails getRegistrationDetails() {
return registrationDetails;
}
public void setRegistrationDetails(RegistrationDetails registrationDetails) {
this.registrationDetails = registrationDetails;
}
public String getSegment() {
return segment;
}
public void setSegment(String segment) {
this.segment = segment;
}
}
|
This is just an example domain class from this Page case study.
RegistrationDetails.java
package example;
import java.util.Date;
public class RegistrationDetails {
private String registrationNumber;
private String placeOfIssue;
private Date issuedDate;
private Car car;
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
public Date getIssuedDate() {
return issuedDate;
}
public void setIssuedDate(Date issuedDate) {
this.issuedDate = issuedDate;
}
public String getPlaceOfIssue() {
return placeOfIssue;
}
public void setPlaceOfIssue(String placeOfIssue) {
this.placeOfIssue = placeOfIssue;
}
public String getRegistrationNumber() {
return registrationNumber;
}
public void setRegistrationNumber(String registrationNumber) {
this.registrationNumber = registrationNumber;
}
}
|
In order to come up with mapping HBM XML file, we need to
understand the basic tables being used to persist these
entities in database (in this example, I have used HSQLDB 1.7.0)
We can't have Car and Registration related tables share primary
key and foreign key relationship, as these may lead to
one to many type of mapping. Instead we shall have to use Unique
constraint on the field/column that is used to tie these two
Entities together for achieving a single row in the dependent
table and a primary key constraint on the main table. By this
we should be able to have a constrained one to one mapping.
So I have decided to use primary key for the car_name column
from car related table, and Unique key constraint for the car_name
in the registration details related table.
DDL db script (HSQLDB 1.7.0 as database) for this example
as follows (Hibernate one to one mapping Tables Definitions):
create table car
(car_name varchar(20), car_model varchar(50),
car_segment varchar(50), primary key (car_name))
create table registration_details
(registration_number varchar(20), issue_place varchar(50),
issue_date date, car_name varchar(20) not null,
primary key(registration_number), unique(car_name))
|
car-registration.hbm.xml (Hibernate one to one mapping HBM file)
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="example">
<class name="Car" table="Car">
<id name="carName" access="property" column="car_name"/>
<property name="model" column="car_model"/>
<property name="segment" column="car_segment"/>
</class>
<class name="RegistrationDetails" table="registration_details">
<id name="registrationNumber" access="property"
column="registration_number"/>
<property name="placeOfIssue" column="issue_place"/>
<property name="issuedDate" column="issue_date" type="java.util.Date"/>
<many-to-one name="car" column="car_name" unique="true" not-null="true"
cascade="persist"/>
</class>
</hibernate-mapping>
|
You might have noticed that instead of using one-to-one tag I have used
many-to-one tag, but with unique as true, not-null as true and cascade as persist,
so as to be able to persist a single record for registration details and
as well as the associated car details in car table as well.
Please see this diagram below, so as to be able to understand how
the mapping configuration HBM file is referring to class and database
model.

This example uses hibernate.cfg.xml file for the configuration related
to creation of Hibernate SessionFactory, as shown below:
hibernate.cfg.xml (Hibernate one to one mapping CFG / configuration file)
<?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>
<!-- Database connection settings -->
<property name="connection.driver_class">
org.hsqldb.jdbcDriver
</property>
<property name="connection.url">
jdbc:hsqldb:hsql://localhost/
</property>
<property name="connection.username">sa</property>
<property name="connection.password"></property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">
org.hibernate.dialect.HSQLDialect
</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">
thread
</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<mapping resource="example/car-registration.hbm.xml"/>
</session-factory>
</hibernate-configuration>
|
Test client for this one to one mapping example is very straight forward.
I am creating a SessionFactory and then getting a Session from it for
persisting both Car and RegistrationDetails POJO as Hibernate Entities.
Client.java (Hibernate one to one mapping Test main class)
// This source is provided on "AS IS" basis.
package example;
import java.util.Calendar;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import demo.interceptor.CaptureSQL;
import demo.profile.Address;
import demo.profile.Contact;
import demo.profile.Person;
import org.apache.log4j.Logger;
public class Client {
private static final SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory from hibernate.cfg.xml
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void createRecord()
{
System.out.println(getSessionFactory());
Session session = getSessionFactory().openSession(new CaptureSQL());
Transaction trx = session.beginTransaction();
trx.begin();
Car car = new Car();
car.setCarName("My Car");
car.setModel("My Model");
car.setSegment("My Segment");
RegistrationDetails regDetails = new RegistrationDetails();
//some hypothetical values are used in this example.
regDetails.setRegistrationNumber("A0002223");
regDetails.setPlaceOfIssue("Ahmedabad");
Calendar c = Calendar.getInstance();
c.set(2007, 01, 04);
regDetails.setIssuedDate(c.getTime());
regDetails.setCar(car);
session.persist(regDetails);
trx.commit();
session.close();
}
/**
* @param args
*/
public static void main(String[] args) {
createRecord();
}
}
|
There is another way of mapping one to one and this is by using
one-to-one tag from Hibernate Framework.
I shall discuss this on my next article, please keep reading and
commenting on these articles for improvement.
Thanks.
If you like to share your comment/suggestions/feedback relating to this Page,
you can do so by droping us an email at
usingframeworks @ gmail . com
with the subject line mentioning URL for this Page (i.e,
/Hibernate-One-To-One-Mapping-Example.php) or use this
LINK.
As per this website's privacy policy, we never disclose your email id,
though we shall post your comments/suggestions/feedback with
your name (optional) and date on this Page. If you don't want your
comments/suggestions/feedback to be shared in this Page, please
mention so in your email to us. Thank you very much.....
If anything missed out , please let me know at
techienjoy at yahoo . com