Hibernate One to One Unidirectional Shared Primary Key

摘要: In this tutorial, we show you how to configure a Hibernate One-to-One Unidirectional Association with shared primary key using either annotations or xml mapping files.

In this tutorial, we show you how to configure a Hibernate One-to-One Unidirectional Association with shared primary key using either annotations or xml mapping files.

  • A one-to-one mapping means that one object can have only one relation – at most.
  • With shared primary key, the primary key of both tables are equal. The foreign key constraint is the primary key of the reference table.
  • A unidirectional relationship means that only one side (the owning side) is able to navigate to the relationship. In the following example only the dog can retrieve the collar reference and not vice versa.

Maven Dependencies

We use Apache Maven to manage the projects dependencies. Add the following dependencies to your projects pom.xml file.

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>6.0.4</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.2.3.Final</version>
</dependency>

Create Model Classes + Annotation Mappings

Following classes are simple POJOs, annotated with standard Java Persistence Api (JPA) annotations. These annotations are the mapping between the Java Class and the corresponding Database Tables. The first POJO is the Dog class.

package com.memorynotfound.hibernate;

import javax.persistence.*;

@Entity
@Table(name = "TBL_DOG")
public class Dog {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "DOG_ID")
    private Integer id;

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

    @PrimaryKeyJoinColumn
    @OneToOne(cascade = CascadeType.ALL, optional = false)
    private Collar collar;

    public Dog() {
    }

    public Dog(String name, Collar collar) {
        this.name = name;
        this.collar = collar;
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Collar getCollar() {
        return collar;
    }

    public void setCollar(Collar collar) {
        this.collar = collar;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", collar=" + collar +
                '}';
    }
}
Note that the @OneToOne annotation has a optional attribute. When this is set to false, hibernate will automatically create the foreign key constraint on the reference table by primary key.

The second POJO is the Collar class.

package com.memorynotfound.hibernate;

import javax.persistence.*;

@Entity
@Table(name = "TBL_COLLAR")
public class Collar {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "COLLAR_ID")
    private Integer id;

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

    public Collar() {
    }

    public Collar(String color) {
        this.color = color;
    }

    public Integer getId() {
        return id;
    }

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

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public String toString() {
        return "Collar{" +
                "id=" + id +
                ", color='" + color + '\'' +
                '}';
    }
}

Hibernate HBM XML Mapping

If you prefer Hibernate XML HBM Mapping files over Annotations, you can use the equivalent hibernate xml mapping for the Dog class. This file is located in the src/main/resources folder and is named Dog.hbm.xml.

Note: the one-to-one element has a constrained attribute – when used – hibernate will create a foreign key constraint on the primary key of the reference table.
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.memorynotfound.hibernate.Dog" table="TBL_DOG">

        <id name="id" type="java.lang.Integer" column="DOG_ID">
            <generator class="identity" />
        </id>

        <property name="name" column="NAME"/>

        <one-to-one name="collar" cascade="all" constrained="true"/>

    </class>
</hibernate-mapping>

And the equivalent hibernate xml mapping for the Collar class. This file is located in the src/main/resources folder and is named Collar.hbm.xml.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.memorynotfound.hibernate.Collar" table="TBL_COLLAR">

        <id name="id" type="java.lang.Integer" column="COLLAR_ID">
            <generator class="identity" />
        </id>

        <property name="color" column="COLOR"/>

    </class>
</hibernate-mapping>

Configure Hibernate Connection Properties

We can configure the database properties using the hibernate hibernate.cfg.xml file, located on the classpath in the src/main/resources folder.

<?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>

        <!-- database connection properties -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/dogstore?serverTimezone=Europe/Brussels</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password"></property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- show mysql queries output in console -->
        <property name="hibernate.show_sql">true</property>

        <!-- manage automatic database creation -->
        <property name="hibernate.hbm2ddl.auto">create-drop</property>

        <!-- add annotated resources here -->
        <mapping class="com.memorynotfound.hibernate.Collar"/>
        <mapping class="com.memorynotfound.hibernate.Dog"/>

    </session-factory>
</hibernate-configuration>

HibernateUtil

This class is used to configure hibernate during startup and create a standalone SessionFactory.

package com.memorynotfound.hibernate;

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

public class HibernateUtil {

    private static final SessionFactory sessionFactory;

    static {
        try {
            sessionFactory = new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static Session getSession() throws HibernateException {
        return sessionFactory.openSession();
    }

    public static void shutdown() {
        sessionFactory.close();
    }
}

Create app

Finally, we can test the application. We create a new Dog object and associate a Collar object. Afterwards, we save the object and commit the transaction.

package com.memorynotfound.hibernate;

import org.hibernate.Session;
import org.hibernate.Transaction;

import java.util.Arrays;
import java.util.List;

public class App {

    public static void main (String...args){

        Session session = HibernateUtil.getSession();
        Transaction tx = session.beginTransaction();

        Collar favoriteCollar = new Collar("spiked-collar");
        Dog pluto = new Dog("pluto", favoriteCollar);

        session.save(pluto);
        tx.commit();

        List dogs = (List)session.createQuery("from Dog").list();
        System.out.println("Dogs: " + Arrays.toString(dogs.toArray()));

        session.close();
        HibernateUtil.shutdown();
    }
}

The previous application prints the following info to the console.

...
Hibernate: insert into TBL_COLLAR (COLOR) values (?)
Hibernate: insert into TBL_DOG (NAME) values (?, ?)
Hibernate: select dog0_.DOG_ID as DOG_ID1_1_, dog0_.NAME as NAME2_1_ from TBL_DOG dog0_
Dogs: [Dog{id=1, name='pluto', collar=Collar{id=1, color='spiked-collar'}}]
...

Records inserted in the database

Download

上一篇: Hibernate Date, Time and DateTime Mapping
下一篇: Hibernate One to One Unidirectional Foreign Key
 评论 ( What Do You Think )
名称
邮箱
网址
评论
验证
   
 

 


  • 微信公众号

  • 我的微信

站点声明:

1、一号门博客CMS,由Python, MySQL, Nginx, Wsgi 强力驱动

2、部分文章或者资源来源于互联网, 有时候很难判断是否侵权, 若有侵权, 请联系邮箱:summer@yihaomen.com, 同时欢迎大家注册用户,主动发布无版权争议的 文章/资源.

3、鄂ICP备14001754号-3, 鄂公网安备 42280202422812号