Last Updated on 12 December 2023   |   Print Email
In this Hibernate tutorial series, we are going to show you how to implement a bidirectional one-to-one association using JPA and Hibernate annotations. The annotations approach is preferred as an alternative to XML descriptor which is described in the tutorial Hibernate One-to-One With Primary Key XML Mapping Example. Let’s recall about the bidirectional one-to-one association by looking at the following entity relationship diagram:As we can see, these two tables share a same primary key (product_id) so that it’s possible to navigate to a corresponding product_detail from a product and vice-versa, thus this is called bidirectional (two-ways) association on primary key.In this tutorial, we will be developing a sample Hibernate program to manage the above product - product_detail association using the following pieces of software (of course you can use newer versions):
The software versions here are the latest as of this writing, but using similar versions is also possible. Here are the steps we should follow:Table of content:
Eclipse Kepler has Maven integration by default, so creating a Maven project is quick and easy. Let’s create a Maven project with the following structure:The project HibernateOne2OnePrimaryKeyAnnotationsExample consists of the following files:
Model classes: Product.java and ProductDetail.java
Hibernate XML configuration file: hibernate.cfg.xml
Test program: ProductsManager.java
Maven project: pom.xml
We specify two primary dependencies of hibernate-core and mysql-connector-java in the pom.xml file as follows:
Here, we use several annotations as you notice: The @Entity, @Table and @Column annotations are straightforward to understand. The others need some further explanations:
@Id and @GeneratedValue: are used in conjunction to map a field as the primary key of the table. Typically, the primary key’s values are auto-generated.
On the Product side, we use the @OneToOne and @PrimaryKeyJoinColumn annotations to tell Hibernate creates a one-to-one association with the ProductDetail and the join column is the primary key column.
On the ProductDetail side, we need to use the @GenericGenerator to specify a foreign key strategy in order to generate values for the product_id column as a foreign key. And the @OneToOne annotation tells Hibernate that the product field is a one-to-one association which is mapped by this productDetail.
Write code for the test program (ProductsManager.java) as follows:
package net.codejava.hibernate;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
/**
* This program demonstrates using Hibernate framework to manage a
* bidirectional one-to-one association on a primary key using
* annotations.
* @author www.codejava.net
*
*/
public class ProductsManager {
public static void main(String[] args) {
// loads configuration and mappings
Configuration configuration = new Configuration().configure();
ServiceRegistryBuilder registry = new ServiceRegistryBuilder();
registry.applySettings(configuration.getProperties());
ServiceRegistry serviceRegistry = registry.buildServiceRegistry();
// builds a session factory from the service registry
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
// obtains the session
Session session = sessionFactory.openSession();
session.beginTransaction();
// creates a new product
Product product = new Product();
product.setName("Civic");
product.setDescription("Comfortable, fuel-saving car");
product.setPrice(20000);
// creates product detail
ProductDetail detail = new ProductDetail();
detail.setPartNumber("ABCDEFGHIJKL");
detail.setDimension("2,5m x 1,4m x 1,2m");
detail.setWeight(1000);
detail.setManufacturer("Honda Automobile");
detail.setOrigin("Japan");
// sets the bi-directional association
product.setProductDetail(detail);
detail.setProduct(product);
// persists the product
session.save(product);
// queries all products
List<Product> listProducts = session.createQuery("from Product").list();
for (Product aProd : listProducts) {
String info = "Product: " + aProd.getName() + "\n";
info += "\tDescription: " + aProd.getDescription() + "\n";
info += "\tPrice: $" + aProd.getPrice() + "\n";
ProductDetail aDetail = aProd.getProductDetail();
info += "\tPart number: " + aDetail.getPartNumber() + "\n";
info += "\tDimension: " + aDetail.getDimension() + "\n";
info += "\tWeight: " + aDetail.getWeight() + "\n";
info += "\tManufacturer: " + aDetail.getManufacturer() + "\n";
info += "\tOrigin: " + aDetail.getOrigin() + "\n";
System.out.println(info);
}
session.getTransaction().commit();
session.close();
}
}
Output of the program:
Hibernate: insert into PRODUCT (description, name, price) values (?, ?, ?)
Hibernate: insert into PRODUCT_DETAIL (dimension,...) values (?, ?, ?, ?, ?, ?)
Hibernate: select product0_.PRODUCT_ID ... from PRODUCT product0_
Product: Civic
Description: Comfortable, fuel-saving car
Price: $20000.0
Part number: ABCDEFGHIJKL
Dimension: 2,5m x 1,4m x 1,2m
Weight: 1000.0
Manufacturer: Honda Automobile
Origin: Japan
Result in the product table:Result in the product_detail table:You can download the sample project attached below, or check the code examples on GitHub here. Related Hibernate One-to-OneTutorials:
Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.
Comments
You need to create a sequence in your Oracle database. See the guide in this tutorial: codejava.net/.../...
I am getting this error
Table 'productsdb.hibernate_sequence' doesn't exist
Please help
Thanks