JPA One To One unidirectional Mapping example

Tien Nguyen - Sep 7 '22 - - Dev Community

In this tutorial, I will show you how to implement Spring JPA One-To-One unidirectional mapping with Hibernate in a Spring Boot example using @OneToOne annotation. You'll know:

  • How to configure Spring Data, JPA, Hibernate to work with Database
  • How to define Data Models and Repository interfaces for JPA One-To-One relationship
  • Way to use Spring JPA to interact with Database for One-To-One association
  • Way to create Spring Rest Controller to process HTTP requests

Full article at: https://www.bezkoder.com/jpa-one-to-one/

Appropriate way to implement JPA/Hibernate One To One mapping

In a relational database, a One-to-One relationship between table A and table B indicates that one row in table A links to only one row in table B, and vice versa.

For example, you need to design data model for a Tutorial Blog in which One Tutorial has corresponding Details (the Date Time it was created on, the author it was created by). So this is a One-to-One association.

You can use a Join Table (with @JoinTable annotation). It stores the primary key values from both entities in a NEW table.

jpa-hibernate-one-to-one-join-table

Another way is to use Shared Primary Key with the Foreign Key is located in the tutorial_details table. Tutorial entity is the parent, and the Tutorial Details is the child.

jpa-hibernate-one-to-one

You can map the child entity with the parent using JPA/Hibernate @OneToOne annotation. And in this case, only the children-side defines the relationship. We call it unidirectional One-to-One association.

Now look at the tutorial_details table that contains a Primary Key column (id) and a Foreign Key column (tutorial_id). You can see that we really need only one tutorial_details (child) row associated with a tutorial (parent) row, and the child data is hardly used in other relationships. So we can omit the child's id column:

jpa-hibernate-one-to-one-example

JPA One To One example

We're gonna create a Spring project from scratch, then we implement JPA/Hibernate One to One Unidirectional Mapping with tutorials and tutorial_details table as following:

jpa-hibernate-one-to-one-example

We also write Rest Apis to perform CRUD operations on the Details entities.

These are APIs that we need to provide:

Methods Urls Actions
POST /api/tutorials/:id/details create new Details for a Tutorial
GET /api/details/:id retrieve Details by :id
GET /api/tutorials/:id/details retrieve Details of a Tutorial
PUT /api/details/:id update Details by :id
PUT /api/tutorials/:id/details update Details of a Tutorial
DELETE /api/details/:id delete Details by :id
DELETE /api/tutorials/:id/details delete Details of a Tutorial
DELETE /api/tutorials/:id delete a Tutorial (and its Details)

Assume that we've had tutorials table like this:

jpa-hibernate-one-to-one-parent-table

Here are the example requests:

  • Create new Details entity: POST /api/tutorials/[:id]/details

jpa-hibernate-one-to-one-create

tutorial_details table after that:

jpa-hibernate-one-to-one-table

  • Retrieve Details of specific Tutorial: GET /api/tutorials/[:id]/details or /api/details/[:id]

jpa-hibernate-one-to-one-retrieve

  • Update Details of specific Tutorial: PUT /api/tutorials/[:id]/details or /api/details/[:id]

jpa-hibernate-one-to-one-update

  • Delete Details of specific Tutorial: DELETE /api/tutorials/[:id]/details or /api/details/[:id]

jpa-hibernate-one-to-one-delete

Check the tutorial_details table, row with tutorial_id=1 were deleted:

jpa-hibernate-one-to-one-delete-db

  • Delete a Tutorial: DELETE /api/tutorials/[:id]

jpa-hibernate-one-to-one-delete-parent

Tutorial (id=3) and its Details were deleted:

jpa-hibernate-one-to-one-delete-parent-table

Let's build our Spring Boot Data JPA One to One example.

Spring Boot One to One example

Technology

  • Java 8
  • Spring Boot 2.7.2 (with Spring Web MVC, Spring Data JPA)
  • H2/MySQL/PostgreSQL
  • Maven 3.8.1

Project Structure

spring-data-jpa-one-to-one-unidirectional

Let me explain it briefly.

Tutorial, TutorialDetails data model class correspond to entity and table tutorials, tutorial_details.
TutorialRepository, TutorialDetailsRepository are interfaces that extends JpaRepository for CRUD methods and custom finder methods. It will be autowired in TutorialController, TutorialDetailsController.
TutorialController, TutorialDetailsController are RestControllers which has request mapping methods for RESTful CRUD API requests.
– Configuration for Spring Datasource, JPA & Hibernate in application.properties.
pom.xml contains dependencies for Spring Boot and MySQL/PostgreSQL/H2 database.

– About exception package, to keep this post straightforward, I won't explain it. For more details, you can read following tutorial:
@RestControllerAdvice example in Spring Boot

Step by step and Github source code can be found at:
https://www.bezkoder.com/jpa-one-to-one/

Further Reading

Custom query with @Query annotation:
Spring JPA @Query example: Custom query in Spring Boot

If you want to add Pagination to this Spring project, you can find the instruction at:
Spring Boot Pagination & Filter example | Spring JPA, Pageable

To sort/order by multiple fields:
Spring Data JPA Sort/Order by multiple Columns | Spring Boot

Handle Exception for this Rest APIs is necessary:

Or way to write Unit Test for the JPA Repository:
Spring Boot Unit Test for JPA Repositiory with @DataJpaTest

You can also know:

Fullstack CRUD App:

Source Code

You can find the complete source code for this tutorial on Github.

One-to-Many: JPA One To Many example with Hibernate and Spring Boot
Many-to-Many: JPA Many to Many example with Hibernate in Spring Boot

You can apply this implementation in following tutorials:

More Derived queries at:
JPA Repository query example in Spring Boot

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .