How to Implement one to one mapping in Spring Data JPA

Implement one-to-one mapping in Spring Data JPA. In case you want to know what is Spring Data JPA check this article https://codedec.com/tutorials/spring-data-jpa-in-spring-boot-with-example/

What is One To One Mapping in Spring?

The One-to-One mapping means when an instance of one entity is associated with an instance of another entity. For eg, consider a relationship between employee and address; one employee will have one address, so this can be shown using @OneToOne mapping in Spring Data JPA.

Following is the  database representation of @OneToOne Relationship

Here, the parent table is ’emp’ which has a foreign key ‘address_id’ referring to address table ‘id’.

The one-to-one mapping can be shown in two ways: unidirectional & bidirectional.

  • unidirectional association: In unidirectional association, the parent entity has a relationship field that refers to the child entity. (In the database, the parent table will have the foreign key of child table)
  • bidirectional association: In bidirectional association, both the parent and child have a relationship referring to each other. (child table contains the foreign key)

Let us implement one-to-one mapping with Spring Data JPA in the Spring boot Application using unidirectional association.

Implement one to one mapping in Spring Data JPA

Step 1: Open IDE STS- Spring Tool Suite

Step 2: Go to File > Spring Starter Project.

Step 3: Now, fill all the fields as shown below and click Next.

Step 4: Now, Add the dependencies of spring data JPA, MYSQL Driver, Lombok, and spring web.

Now, wait for some time and your project structure will be ready. Go to the pom.xml file and you will see the following dependencies will be added automatically.

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <scope>runtime</scope>
</dependency>

Create a Database in MYSQL

create database one_to_onejpa;

Configure application. properties file

This is the file provided by spring boot to configure JDBC URL, username, password, and driver class name. Also, configure JPA-related information.

spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/one_to_oneJPA
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name =com.mysql.jdbc.Driver
spring.jpa.show-sql= true
## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
#To format SQL queries generated by Hibernate
spring.jpa.properties.hibernate.format_sql=true
#change port number
server.port=8888
  • spring.jpa.hibernate.ddl-auto is set to update so that whatever changes we will do will be reflected in the schema.
  • spring.datasource.url is used to set the URL of the MYSQL DB.
  • spring.datasource.username is used to set the username and spring. datasource. password is used to set the password.
  • spring.datasource.driver-class-name is used to set the driver class name.
  • spring.jpa.show-sql is set to true to show SQL generated by the Hibernate.
  • spring.jpa.properties.hibernate.dialect is used to generate better SQL for the chosen database.
  • spring.jpa.properties.hibernate.format_sql is set to true to format SQL queries.
  • server.port is set to 8888.

Create an Entity Class

Create two Entity Employee and Address that will have an OneToOne relationship.

Employee.java

package com.abc.example.mapping.model;

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

import lombok.Data;

@Data
@Entity
@Table(name = "emp")
public class Employee {

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private long id;
 @Column(name = "emp_name")
 private String empName;
 @OneToOne(cascade = CascadeType.ALL)
 @JoinColumn(name = "address_id",referencedColumnName = "id")
 private Address address;
}

Address.java

package com.abc.example.mapping.model;

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

import lombok.Data;

@Data
@Entity
@Table(name = "address")
public class Address {

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private long id;
 @Column(name = "zip_code")
 private String zipCode;
 @Column(name = "state")
 private String state;
 @Column(name = "country")
 private String country;
}
  • @Entity is used to annotate the classes to indicate that they are JPA entities.
  • @Table annotation is used to specify the name of the table that should be mapped with entities.
  • @Id annotation is used for the primary key.
  • The relationship between entities is shown using @OneToOne mapping. The source entity Employee has a field of target entity mapped with @OneToOne. (In the database, the employee table will have a foreign key referring to address table id)
  • @JoinColumn is used to specify the foreign key column.
  • I have used the Lombok library to remove boilerplate code. In case you want to know what is Lombok check this article https://codedec.com/tutorials/how-to-configure-lombok-into-eclipse/
  • Cascade.ALL will make sure that all persistence events that are performed on the parent object will be transferred to the child entity.

Create Repository Interface

The repository here is the DAO layer, which performs all the database operations. EmployeeRepository and AddressRepository interface is created which will extend JPARepository<ClassName, ID>.

EmployeeRepository

package com.abc.example.mapping.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.abc.example.mapping.model.Employee;
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long>{

}

AddressRepository

package com.abc.example.mapping.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.abc.example.mapping.model.Address;

@Repository
public interface AddressRepository extends JpaRepository<Address, Long> {

 Address findByZipCode(String id) ;
}

Now, Go to OneToOneJpaApplication class and test our one-to-one relationship.

package com.abc.example.mapping;

import java.util.List;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

import com.abc.example.mapping.model.Address;
import com.abc.example.mapping.model.Employee;
import com.abc.example.mapping.repository.AddressRepository;
import com.abc.example.mapping.repository.EmployeeRepository;

@SpringBootApplication
public class OneToOneJpaApplication {

 public static void main(String[] args) {
  ApplicationContext context = SpringApplication.run(OneToOneJpaApplication.class, args);
  EmployeeRepository employeeRepository = context.getBean(EmployeeRepository.class);
  AddressRepository addressRepository = context.getBean(AddressRepository.class);

  // Save into db

  Address address = new Address();
  address.setZipCode("425201");
  address.setCountry("USA");
  address.setState("Newyork");
  Employee employee = new Employee();
  employee.setEmpName("Nicolas");
  employee.setAddress(address);
  employeeRepository.save(employee);

 }

}

Now, Go to Run As > Spring Boot App. The tables will be created inside the database along with mapping.

Now, if we want to fetch records add the following code in the Application class:

// fetching records
  List<Employee> list = employeeRepository.findAll();
  System.out.println(list);

  Address addresses = addressRepository.findByZipCode("425201");
  System.out.println(addresses);

Run the Application once again and see the console for output. In this way, we learned how to map one-to-one relationships in Spring Data JPA.