Hibernate one-to-one mapping using Annotations

In this article, we will create one-to-one mapping between “phone” and “phone_detail” tables. Here, one phone can have one phone_detail record.

To create the relationships, lets first create the tables.

hibernate one-to-one association
 

Creating tables

We have set the “hibernate.hbm2ddl.auto” parameter to “create” which should create the tables when the program is run. But you can also create the tables manually with these scripts.

    create table phone (
        id bigint not null auto_increment,
        number varchar(255),
        detail_id bigint,
        primary key (id)
    )
    create table phone_detail (
        id bigint not null auto_increment,
        provider varchar(255),
        primary key (id)
    )
    alter table phone 
        add constraint FK_egb5c50ricvp10rm66x3ist89 
        foreign key (detail_id) 
        references phone_detail (id)

Here is how the hibernate.cfg.xml looks like with hbm2ddl set to “create”.

<?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 name="">
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.password">passwrd</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/TestDB</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.format_sql">true</property>
    <property name="hibernate.hbm2ddl.auto">create</property>

    <mapping class="com.topjavatutorial.oneone.PhoneDetail" />
    <mapping class="com.topjavatutorial.oneone.Phone" />
  </session-factory>
</hibernate-configuration>

 

Entity classes

Let’s create the Phone and PhoneDetail entity classes.

package com.topjavatutorial.oneone;

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

@Entity
@Table(name = "phone")
public class Phone {
  @Id
  @GeneratedValue
  private Long id;

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

  @OneToOne(cascade = CascadeType.ALL)
  @JoinColumn(name = "detail_id")
  private PhoneDetail detail;

  public Long getId() {
    return id;
  }

  public String getNumber() {
    return number;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public void setNumber(String number) {
    this.number = number;
  }

  public PhoneDetail getDetail() {
    return detail;
  }

  public void setDetail(PhoneDetail detail) {
    this.detail = detail;
  }

  @Override
  public String toString() {
    return "Phone" + "\n Id: " + this.id + "\n Number: " + this.number
        + "\n Provider: " + this.detail.getProvider();
  }
}

package com.topjavatutorial.oneone;

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

@Entity
@Table(name = "phone_detail")
public class PhoneDetail {
  @Id
  @GeneratedValue
  @Column(name = "id")
  private Long id;
  private String provider;

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getProvider() {
    return provider;
  }

  public void setProvider(String provider) {
    this.provider = provider;
  }
}

 

Insert data to phone and phone_detail tables

For inserting data to the tables, lets first add the following class to obtain a SessionFactory.

package com.topjavatutorial.oneone;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

  private static final 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;
  }

}

Now, the following code actually inserts the records and then display the query results.

package com.topjavatutorial.oneone;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.topjavatutorial.onemany.HibernateUtil;

public class DemoOneToOneMapping {

  public static void main(String[] args) {

    PhoneDetail detail = new PhoneDetail();
    detail.setProvider("AT&T");

    Phone phone = new Phone();
    phone.setNumber("123-456-7890");
    phone.setDetail(detail);

    SessionFactory factory = HibernateUtil.getSessionFactory();
    Session session = factory.openSession();
    session.getTransaction().begin();
    session.save(phone);
    session.getTransaction().commit();

    Criteria criteria = session.createCriteria(Phone.class);
    Phone phone1 = (Phone) criteria.uniqueResult();
    System.out.println(phone1);
  }

}

hibernate one-to-one

Output :

Hibernate:
create table phone (
id bigint not null auto_increment,
number varchar(255),
detail_id bigint,
primary key (id)
)
Hibernate:
create table phone_detail (
id bigint not null auto_increment,
provider varchar(255),
primary key (id)
)
Hibernate:
alter table phone
add constraint FK_egb5c50ricvp10rm66x3ist89
foreign key (detail_id)
references phone_detail (id)

Dec 25, 2016 8:39:43 AM org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: HHH000230: Schema export complete

Hibernate:
insert
into
phone_detail
(provider)
values
(?)
Hibernate:
insert
into
phone
(detail_id, number)
values
(?, ?)
 

Retrieve data using Phone record

Criteria criteria = session.createCriteria(Phone.class);
Phone phone1 = (Phone) criteria.uniqueResult();
System.out.println(phone1);

Output:

Hibernate:
select
this_.id as id1_0_1_,
this_.detail_id as detail_i3_0_1_,
this_.number as number2_0_1_,
phonedetai2_.id as id1_1_0_,
phonedetai2_.provider as provider2_1_0_
from
phone this_
left outer join
phone_detail phonedetai2_
on this_.detail_id=phonedetai2_.id
Phone
Id: 1
Number: 123-456-7890
Provider: AT&T

 

Bidirectional one-to-one mapping

To be able to achieve Bidirectional relationship, we need to update the PhoneDetail entity so that its aware of the Phone entity.

 package com.topjavatutorial.oneone;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name = "phone_detail")
public class PhoneDetail {
  @Id
  @GeneratedValue
  @Column(name = "id")
  private Long id;
  private String provider;

  @OneToOne(mappedBy = "detail", cascade = CascadeType.ALL)
  private Phone phone;

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getProvider() {
    return provider;
  }

  public void setProvider(String provider) {
    this.provider = provider;
  }

  public Phone getPhone() {
    return phone;
  }

  public void setPhone(Phone phone) {
    this.phone = phone;
  }

  @Override
  public String toString() {
    return "PhoneDetail" + "\n Id: " + this.id + "\n Provider: "
        + this.provider + "\n Phone: " + this.phone.getNumber();
  }
}
 

Now, if we insert the record to the tables and query based on the PhoneDetail information, we should be able to get both the Phone and PhoneDetails data.

     PhoneDetail detail = new PhoneDetail();
    detail.setProvider("AT&T");

    Phone phone = new Phone();
    phone.setNumber("123-456-7890");
    phone.setDetail(detail);
    detail.setPhone(phone);
    
    SessionFactory factory = HibernateUtil.getSessionFactory();
    Session session = factory.openSession();
    session.getTransaction().begin();
    session.save(phone);
    session.getTransaction().commit();
    
    Criteria criteria1 = session.createCriteria(PhoneDetail.class);
    PhoneDetail detail1= (PhoneDetail) criteria1.uniqueResult();
    System.out.println(detail1);
 

Output :

Hibernate:
insert
into
phone_detail
(provider)
values
(?)
Hibernate:
insert
into
phone
(detail_id, number)
values
(?, ?)
Hibernate:
select
this_.id as id1_1_1_,
this_.provider as provider2_1_1_,
phone2_.id as id1_0_0_,
phone2_.detail_id as detail_i3_0_0_,
phone2_.number as number2_0_0_
from
phone_detail this_
left outer join
phone phone2_
on this_.id=phone2_.detail_id
PhoneDetail
Id: 1
Provider: AT&T
Phone: 123-456-7890
 

© 2016, https:. All rights reserved. On republishing this post, you must provide link to original post

Leave a Reply.. code can be added in <code> </code> tags