Mapping - @OneToOne

A one-to-one mapping in JPA (Java Persistence API) represents a relationship where each entity instance in one table is associated with exactly one entity instance in another table. This tutorial will explain the concept with an example using EntityManager for managing persistence. We'll cover the following steps:

Example Scenario

Let's assume we have two entities:

  1. User - Stores basic user information.
  2. UserProfile - Stores additional user profile details.

Each User has exactly one UserProfile, and each UserProfile belongs to exactly one User.


Step-by-Step Implementation

Step 1: Create Entity Classes

  1. User Entity

import jakarta.persistence.*; @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @OneToOne(mappedBy = "user", cascade = CascadeType.ALL) private UserProfile userProfile; // Getters and setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public UserProfile getUserProfile() { return userProfile; } public void setUserProfile(UserProfile userProfile) { this.userProfile = userProfile; userProfile.setUser(this); // Ensure bi-directional association } }
  1. UserProfile Entity

import jakarta.persistence.*; @Entity public class UserProfile { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String address; @OneToOne @JoinColumn(name = "user_id", referencedColumnName = "id") private User user; // Getters and setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } }

Step 2: Persistence Configuration

Configure your persistence.xml for JPA:

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1"> <persistence-unit name="example-unit"> <class>User</class> <class>UserProfile</class> <properties> <property name="jakarta.persistence.jdbc.url" value="jdbc:h2:mem:testdb"/> <property name="jakarta.persistence.jdbc.user" value="sa"/> <property name="jakarta.persistence.jdbc.driver" value="org.h2.Driver"/> <property name="jakarta.persistence.jdbc.password" value=""/> <property name="hibernate.hbm2ddl.auto" value="update"/> <property name="hibernate.show_sql" value="true"/> </properties> </persistence-unit> </persistence>

Step 3: Using EntityManager

Create a main class to persist and retrieve entities.

import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.Persistence; public class OneToOneExample { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("example-unit"); EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); // Create User and UserProfile User user = new User(); user.setName("John Doe"); UserProfile profile = new UserProfile(); profile.setAddress("123 Main Street"); // Establish relationship user.setUserProfile(profile); // Persist entities em.persist(user); em.getTransaction().commit(); // Fetch and display User fetchedUser = em.find(User.class, user.getId()); System.out.println("User: " + fetchedUser.getName()); System.out.println("Profile Address: " + fetchedUser.getUserProfile().getAddress()); em.close(); emf.close(); } }

Key Points:

  1. Mapping Annotation:

    • @OneToOne: Declares the relationship.
    • mappedBy: Defines the owner of the relationship.
    • @JoinColumn: Specifies the foreign key column.
  2. EntityManager:

    • Use em.persist() to save entities.
    • Use em.find() to retrieve entities.
  3. Cascade:

    • CascadeType.ALL ensures that related UserProfile is persisted when saving User.

This example sets up a one-to-one relationship and demonstrates persistence and retrieval using EntityManager. Let me know if you'd like to dive deeper into any part!

Comments