• Java
    • JAXB Tutorial
      • What is JAXB
      • JAXB Marshalling Example
      • JAXB UnMarshalling Example
  • Spring Tutorial
    • Spring Core Tutorial
    • Spring MVC Tutorial
      • Quick Start
        • Flow Diagram
        • Hello World Example
        • Form Handling Example
      • Handler Mapping
        • BeanNameUrlHandlerMapping
        • ControllerClassNameHandlerMapping
        • SimpleUrlHandlerMapping
      • Validation & Exception Handling
        • Validation+Annotations
        • Validation+ResourceBundle
        • @ExceptionHandler
        • @ControllerAdvice
        • Custom Exception Handling
      • Form Tag Library
        • Textbox Example
        • TextArea Example
        • Password Example
        • Dropdown Box Example
        • Checkboxes Example
        • Radiobuttons Example
        • HiddenValue Example
      • Misc
        • Change Config file name
    • Spring Boot Tutorial
  • Hibernate Tutorial
  • REST Tutorial
    • JAX-RS REST @PathParam Example
    • JAX-RS REST @QueryParam Example
    • JAX-RS REST @DefaultValue Example
    • JAX-RS REST @Context Example
    • JAX-RS REST @MatrixParam Example
    • JAX-RS REST @FormParam Example
    • JAX-RS REST @Produces Example
    • JAX-RS REST @Consumes Example
    • JAX-RS REST @Produces both XML and JSON Example
    • JAX-RS REST @Consumes both XML and JSON Example
  • Miscellaneous
    • JSON Parser
      • Read a JSON file
      • Write JSON object to File
      • Read / Write JSON using GSON
      • Java Object to JSON using JAXB
    • CSV Parser
      • Read / Write CSV file
      • Read/Parse/Write CSV File – OpenCSV
      • Export data into a CSV File
      • CsvToBean and BeanToCsv – OpenCSV

JavaInterviewPoint

Java Development Tutorials

Spring Boot JPA One To One Example with MySQL | Unidirectional & Bidirectional

September 25, 2019 by javainterviewpoint Leave a Comment

In this article, we will learn how to create a Spring Boot JPA One To One mapping using Spring Data JPA with Foreign Key. In this approach, we will have two tables with different primary keys. The primary key of the STUDENT table (ID) will act as a foreign key for the PASSPORT table and PASSPORT table will have its own primary key (ID).

Creating table

Create STUDENT & PASSPORT Table, simply Copy and Paste the following MySQL query in the query editor to get the table created.

CREATE TABLE STUDENT
(
	ID INT NOT NULL,
        NAME VARCHAR(50) NOT NULL,
        PRIMARY KEY(ID)
);
   
insert into STUDENT (ID, NAME) values(1, 'John');
insert into STUDENT (ID, NAME) values(2, 'Smith');
insert into STUDENT (ID, NAME) values(3, 'Tom');
insert into STUDENT (ID, NAME) values(4, 'Bruce');
   
CREATE TABLE PASSPORT
(
	ID INT NOT NULL,
        NUMBER VARCHAR(50) NOT NULL,
        STUDENT_ID INT NOT NULL,
        FOREIGN KEY (STUDENT_ID) REFERENCES STUDENT (ID)
);
   
insert into PASSPORT (ID, NUMBER, STUDENT_ID) values(1,'A123456', 1);
insert into PASSPORT (ID, NUMBER, STUDENT_ID) values(2, 'B123456', 2);
insert into PASSPORT (ID, NUMBER, STUDENT_ID) values(3, 'C123456', 3);

Folder Structure:

Spring Boot JPA Folder Structure

  • Create a Maven project (maven-archetype-quickstart) “SpringBootOneToOne” and create packages for our source files “com.javainterviewpoint“, “com.javainterviewpoint.controller”, “com.javainterviewpoint.model” and “com.javainterviewpoint.repository” under  src/main/java 
  • Now add the following dependency in the POM.xml
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.javainterviewpoint</groupId>
      <artifactId>SpringBootOneToOne</artifactId>
      <packaging>war</packaging>
      <version>0.0.1-SNAPSHOT</version>
      <name>SpringBootOneToOne Maven Webapp</name>
      <url>http://maven.apache.org</url>
      <parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>2.1.7.RELEASE</version>
    	</parent>
    
    	<properties>
    		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    		<java.version>1.8</java.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-data-jpa</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    
    		<dependency>
    			<groupId>mysql</groupId>
    			<artifactId>mysql-connector-java</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-test</artifactId>
    			<scope>test</scope>
    		</dependency>
    	</dependencies>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    			</plugin>
    		</plugins>
    	</build>
    </project>
  • Create application.properties file under src/main/resources directory and provide the MySQL Connections and JPA Properties
#MySQL Connection settings
spring.datasource.driver = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/mydb
spring.datasource.username = root
spring.datasource.password = root

#JPA properties 
spring.jpa.show-sql = true
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

The spring-boot-starter-parent is a special starter, it provides useful Maven defaults. Since we are developing a web application we also need to add a spring-boot-starter-web dependency. This will add dependencies such Tomcat, Jackson, Spring boot etc which is required to create a web app.

spring-boot-starter-data-jpa uses Spring Data JPA with Hibernate as the implementation

Other interesting articles which you may like …

  • Spring Data JPA One To One Foreign Key Example
  • Spring Data JPA One To Many Foreign Key Example
  • Spring Data JPA Many To Many Foreign Key Example
  • Hibernate One To One Bidirectional Mapping – Foreign Key
  • Hibernate One To One Bidirectional Mapping – Primary Key
  • Hibernate Many To Many Mapping Example – Annotation
  • Hibernate One To Many Mapping XML Example
  • Hibernate One To One Mapping XML Example with Foreign Key
  • Hibernate One To One Bidirectional Mapping XML Example with Primary Key
  • Hibernate Many To Many Mapping Example – XML Mapping
  • Spring Boot Exception Handling – @RestControllerAdvice + @ExceptionHandler
  • Spring Boot Security Database Authentication
  • Spring Boot Security Basic Authentication
  • Spring Boot @ConfigurationProperties Example
  • Spring Boot auto-configuration @SpringBootApplication
  • Spring Boot Thymeleaf Example
  • Spring Boot JPA Tutorial
  • Spring Boot Tomcat JDBC Connection Pool
  • Spring Boot Logging – Logback
  • Spring Boot Log4j2 Example
  • Spring Boot HikariCP Connection Pool
  • Spring Boot JDBC Connection Pool
  • Spring Boot RESTful Web Services Example
  • Spring Boot Kotlin RESTful Web Services
  • Spring Boot with Kotlin Hello World Example
  • Spring Boot Hello World Example with Maven
  • Spring Boot Hello World Example in Eclipse
  • How to Create Deployable WAR | Spring Boot | SpringBootServletInitializer
  • Spring Boot Change Embedded Tomcat default port
  • Spring Boot CRUDRepository Example- Spring Data JPA

Spring Boot JPA One To One Example with MySQL – Unidirectional

Spring Boot JPA One To One Example

Dependency Tree

[INFO] -------------< com.javainterviewpoint:SpringBootOneToOne >--------------
[INFO] Building SpringBootOneToOne Maven Webapp 0.0.1-SNAPSHOT
[INFO] --------------------------------[ war ]---------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:3.1.1:tree (default-cli) @ SpringBootOneToOne ---
[INFO] com.javainterviewpoint:SpringBootOneToOne:war:0.0.1-SNAPSHOT
[INFO] +- org.springframework.boot:spring-boot-starter-data-jpa:jar:2.1.7.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-aop:jar:2.1.7.RELEASE:compile
[INFO] |  |  +- org.springframework:spring-aop:jar:5.1.9.RELEASE:compile
[INFO] |  |  \- org.aspectj:aspectjweaver:jar:1.9.4:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-jdbc:jar:2.1.7.RELEASE:compile
[INFO] |  |  +- com.zaxxer:HikariCP:jar:3.2.0:compile
[INFO] |  |  \- org.springframework:spring-jdbc:jar:5.1.9.RELEASE:compile
[INFO] |  +- javax.transaction:javax.transaction-api:jar:1.3:compile
[INFO] |  +- javax.xml.bind:jaxb-api:jar:2.3.1:compile
[INFO] |  |  \- javax.activation:javax.activation-api:jar:1.2.0:compile
[INFO] |  +- org.hibernate:hibernate-core:jar:5.3.10.Final:compile
[INFO] |  |  +- org.jboss.logging:jboss-logging:jar:3.3.2.Final:compile
[INFO] |  |  +- javax.persistence:javax.persistence-api:jar:2.2:compile
[INFO] |  |  +- org.javassist:javassist:jar:3.23.2-GA:compile
[INFO] |  |  +- net.bytebuddy:byte-buddy:jar:1.9.16:compile
[INFO] |  |  +- antlr:antlr:jar:2.7.7:compile
[INFO] |  |  +- org.jboss:jandex:jar:2.0.5.Final:compile
[INFO] |  |  +- com.fasterxml:classmate:jar:1.4.0:compile
[INFO] |  |  +- org.dom4j:dom4j:jar:2.1.1:compile
[INFO] |  |  \- org.hibernate.common:hibernate-commons-annotations:jar:5.0.4.Final:compile
[INFO] |  +- org.springframework.data:spring-data-jpa:jar:2.1.10.RELEASE:compile
[INFO] |  |  +- org.springframework.data:spring-data-commons:jar:2.1.10.RELEASE:compile
[INFO] |  |  +- org.springframework:spring-orm:jar:5.1.9.RELEASE:compile
[INFO] |  |  +- org.springframework:spring-context:jar:5.1.9.RELEASE:compile
[INFO] |  |  +- org.springframework:spring-tx:jar:5.1.9.RELEASE:compile
[INFO] |  |  +- org.springframework:spring-beans:jar:5.1.9.RELEASE:compile
[INFO] |  |  \- org.slf4j:slf4j-api:jar:1.7.26:compile
[INFO] |  \- org.springframework:spring-aspects:jar:5.1.9.RELEASE:compile
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.1.7.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:2.1.7.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot:jar:2.1.7.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:2.1.7.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:2.1.7.RELEASE:compile
[INFO] |  |  |  +- ch.qos.logback:logback-classic:jar:1.2.3:compile
[INFO] |  |  |  |  \- ch.qos.logback:logback-core:jar:1.2.3:compile
[INFO] |  |  |  +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.11.2:compile
[INFO] |  |  |  |  \- org.apache.logging.log4j:log4j-api:jar:2.11.2:compile
[INFO] |  |  |  \- org.slf4j:jul-to-slf4j:jar:1.7.26:compile
[INFO] |  |  +- javax.annotation:javax.annotation-api:jar:1.3.2:compile
[INFO] |  |  \- org.yaml:snakeyaml:jar:1.23:runtime
[INFO] |  +- org.springframework.boot:spring-boot-starter-json:jar:2.1.7.RELEASE:compile
[INFO] |  |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.9.9:compile
[INFO] |  |  |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.9.0:compile
[INFO] |  |  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.9.9:compile
[INFO] |  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.9.9:compile
[INFO] |  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.9.9:compile
[INFO] |  |  \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.9.9:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.1.7.RELEASE:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:9.0.22:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-el:jar:9.0.22:compile
[INFO] |  |  \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:9.0.22:compile
[INFO] |  +- org.hibernate.validator:hibernate-validator:jar:6.0.17.Final:compile
[INFO] |  |  \- javax.validation:validation-api:jar:2.0.1.Final:compile
[INFO] |  +- org.springframework:spring-web:jar:5.1.9.RELEASE:compile
[INFO] |  \- org.springframework:spring-webmvc:jar:5.1.9.RELEASE:compile
[INFO] |     \- org.springframework:spring-expression:jar:5.1.9.RELEASE:compile
[INFO] +- mysql:mysql-connector-java:jar:8.0.17:compile
[INFO] \- org.springframework.boot:spring-boot-starter-test:jar:2.1.7.RELEASE:test
[INFO]    +- org.springframework.boot:spring-boot-test:jar:2.1.7.RELEASE:test
[INFO]    +- org.springframework.boot:spring-boot-test-autoconfigure:jar:2.1.7.RELEASE:test
[INFO]    +- com.jayway.jsonpath:json-path:jar:2.4.0:test
[INFO]    |  \- net.minidev:json-smart:jar:2.3:test
[INFO]    |     \- net.minidev:accessors-smart:jar:1.2:test
[INFO]    |        \- org.ow2.asm:asm:jar:5.0.4:test
[INFO]    +- junit:junit:jar:4.12:test
[INFO]    +- org.assertj:assertj-core:jar:3.11.1:test
[INFO]    +- org.mockito:mockito-core:jar:2.23.4:test
[INFO]    |  +- net.bytebuddy:byte-buddy-agent:jar:1.9.16:test
[INFO]    |  \- org.objenesis:objenesis:jar:2.6:test
[INFO]    +- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO]    +- org.hamcrest:hamcrest-library:jar:1.3:test
[INFO]    +- org.skyscreamer:jsonassert:jar:1.5.0:test
[INFO]    |  \- com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:test
[INFO]    +- org.springframework:spring-core:jar:5.1.9.RELEASE:compile
[INFO]    |  \- org.springframework:spring-jcl:jar:5.1.9.RELEASE:compile
[INFO]    +- org.springframework:spring-test:jar:5.1.9.RELEASE:test
[INFO]    \- org.xmlunit:xmlunit-core:jar:2.6.3:test
[INFO] ------------------------------------------------------------------------

Defining JPA Entities – Shared Primary Key in JPA

Passport Entity

Create Passport.java under the package com.javainterviewpoint.model

package com.javainterviewpoint.model;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name="PASSPORT")
public class Passport
{	
	@Id
	private int id;
	
	private String number;
	
	@OneToOne(cascade = CascadeType.ALL)
	private Student student;

	public Passport()
	{
		super();
	}

	public Passport(int id, String number, Student student)
	{
		super();
		this.id = id;
		this.number = number;
		this.student = student;
	}

	public int getId()
	{
		return id;
	}

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

	public String getNumber()
	{
		return number;
	}

	public void setNumber(String number)
	{
		this.number = number;
	}

	public Student getStudent()
	{
		return student;
	}

	public void setStudent(Student student)
	{
		this.student = student;
	}

	@Override
	public String toString()
	{
		return "Passport [id=" + id + ", number=" + number + ", student=" + student + "]";
	}
}

Our Passport class is a simple POJO class consisting of the getters and setters for the Passport properties (id, name).

In the POJO class, we have used the below JPA Annotations.

  1. @Entity – This annotation will mark our Passport class as an Entity Bean.
  2. @Table – @Table annotation will map our class to the corresponding database table. You can also specify other attributes such as indexes, catalog, schema, uniqueConstraints. The @Table annotation is an optional annotation if this annotation is not provided then the class name will be used as the table name.
  3. @Id –  The @Id annotation marks the particular field as the primary key of the Entity.
  4. @OneToOne – This annotation indicates that the Passport entity owns the relationship. cascade = CascadeType.ALL , This attribute applies the cascading effect to the related entity as well. Whenever we perform any update/modification operation on the Passport entity it will be cascaded to the Student entity as well.

Student Entity

Create Student.java also under the package com.javainterviewpoint.model

package com.javainterviewpoint.model;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "STUDENT")
public class Student
{
	@Id
	private int id;
	
	private String name;

	public Student()
	{
		super();
	}

	public Student(int id, String name)
	{
		super();
		this.id = id;
		this.name = name;
	}

	public int getId()
	{
		return id;
	}

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

	public String getName()
	{
		return name;
	}

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

	@Override
	public String toString()
	{
		return "Student [id=" + id + ", name=" + name + "]";
	}
}

Adding the Repository – CrudRepository

We simply have created an interface PassportRepository which in turn extends CrudRepository that’s all we have to do, Spring Data will automatically create an implementation in the runtime.

CrudRepository will by default provide you with the generic methods like save(), findAll(), insert(), etc.. Out-of-the-box we can also add our custom methods and Spring Data has the query builder mechanism built in which strips the prefixes find…By, read…By, and get…By

We have defined a single method getStudent() which retrieves the Student object from the STUDENT table.

package com.javainterviewpoint.repository;

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import com.javainterviewpoint.model.Passport;
import com.javainterviewpoint.model.Student;

@Repository
public interface PassportRepository extends CrudRepository<Passport, Integer>
{
	@Query("select s from Student s where id= :studentid")
	public Student getStudent(int studentid);
}

Rest Controller – PassportController

package com.javainterviewpoint.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.javainterviewpoint.model.Passport;
import com.javainterviewpoint.model.Student;
import com.javainterviewpoint.repository.PassportRepository;

@RestController
public class PassportController
{
	@Autowired
	public PassportRepository passportRepository;

	@GetMapping("/passport/{id}")
	public Passport getPassportById(@PathVariable("id") int id)
	{
		Passport passport = passportRepository.findById(id).get();

		return passport;
	}

	@GetMapping("/passports")
	public List<Passport> getAllPassport()
	{
		List<Passport> passportList = new ArrayList<>();
		Iterable<Passport> passport = passportRepository.findAll();

		for (Passport p : passport)
		{
			passportList.add(p);
		}

		return passportList;
	}

	@PostMapping("/passport/{studentid}")
	public Passport createPassport(@PathVariable("studentid") int studentid,
				       @RequestBody Passport passport)
	{
		Student student = passportRepository.getStudent(studentid);
		
		passport.setStudent(student);
		
		passportRepository.save(passport);

		return getPassportById(passport.getId());
	}
	
	@DeleteMapping("/passport/{id}")
	public List<Passport> deletePassport(@PathVariable("id") int id)
	{
		passportRepository.deleteById(id);

		return getAllPassport();
	}
}

We have annotated our “StudentController” class with @RestController, In Spring 4 @RestController annotation is introduced it is a combination of @Controller + @ResponseBody. So when using @RestController, you do not need to use @ResponseBody it is optional now

Main Application – App.java

package com.javainterviewpoint;

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

@SpringBootApplication
public class App
{
	public static void main(String[] args)
	{
		SpringApplication.run(App.class, args);
	}
}

The App class main() method is the triggering point of our application, it in-turn calls Spring Boot’s SpringApplication class run() method which bootstrap our App application and starts the tomcat server. We need to pass our App.class as an argument to our run() method.

Let’s Run our Application!

Select the Project –>Run As –> Run Configuration –>Maven –> New Configuration. In the Main tab, key in the Goals as “spring-boot:run” and click on Run.

Get a Single Passport

Using POSTMAN or any other Rest Client and place a GET request on the URL http://localhost:8080/passport/1

Spring One To One Passport GET

Get All the Passport

Using POSTMAN or any other Rest Client and place a GET request on the URL http://localhost:8080/passports

Passport GET ALL

Create a Passport

Place a POST request on the URL http://localhost:8080/passport/4

Make sure to pass the passport details in the body of the request

{
    “id” : 4,
    “number” : “D123456”
}

We are passing the Student id ‘4’ in the above URL for which the Passport needs to be created.

Create Passport Post

Delete Passport

Place a DELETE request on the URL http://localhost:8080/passport/4

Passport Delete

Spring Boot JPA One To One Example with MySQL – Bidirectional

Till now what we have seen is One To One unidirectional approach. We are able to access Student details through Passport entity only, whereas the vice-versa Passport details through the Student entity is not possible.

In order to make it bidirectional, we need to make some minor modifications to the Student Entity class and create a new repository for Student.

Student Entity

package com.javainterviewpoint.model;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;

@Entity
@Table(name = "STUDENT")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class Student
{
	@Id
	private int id;
	
	private String name;

	@OneToOne(mappedBy = "student", cascade = CascadeType.ALL)
	private Passport passport;

	public Student()
	{
		super();
	}

	public Student(int id, String name, Passport passport)
	{
		super();
		this.id = id;
		this.name = name;
		this.passport = passport;
	}

	public int getId()
	{
		return id;
	}

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

	public String getName()
	{
		return name;
	}

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

	public Passport getPassport()
	{
		return passport;
	}

	public void setPassport(Passport passport)
	{
		this.passport = passport;
	}

	@Override
	public String toString()
	{
		return "Student [id=" + id + ", name=" + name + ", passport=" + passport + "]";
	}
}

We didn’t have Passport class reference in Student entity before, now we have added it and annotated it with @OneToOne annotation and we have added mappedBy attribute to it.

mappedBy =”student” – The mappedBy attribute on the Student entity informs Spring Data that it is not the owner for the relationship.

We have also added a new annotation @JsonIdentityInfo in both the Student and Passport entities in order to prevent Cyclic dependency and Stackoverflow issue

We will be getting the below error when we have not added the annotation @JsonIdentityInfo due to Cyclic dependency 

java.lang.StackOverflowError: null
	at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_211]
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[na:1.8.0_211]
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[na:1.8.0_211]
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:468) ~[na:1.8.0_211]
	at java.net.URLClassLoader.access$100(URLClassLoader.java:74) ~[na:1.8.0_211]
	at java.net.URLClassLoader$1.run(URLClassLoader.java:369) ~[na:1.8.0_211]
	at java.net.URLClassLoader$1.run(URLClassLoader.java:363) ~[na:1.8.0_211]
	at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_211]
	at java.net.URLClassLoader.findClass(URLClassLoader.java:362) ~[na:1.8.0_211]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_211]
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) ~[na:1.8.0_211]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_211]
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:737) ~[jackson-databind-2.9.9.jar:2.9.9]
	at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.9.jar:2.9.9]
	at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.9.jar:2.9.9]
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.9.jar:2.9.9]
	at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.9.jar:2.9.9]
	at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.9.jar:2.9.9]
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.9.jar:2.9.9]
	at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.9.jar:2.9.9]
	at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.9.jar:2.9.9]
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.9.jar:2.9.9]

StudentRepository

Let’s create a simple CrudRepository for our Student Entity.

package com.javainterviewpoint.repository;

import org.springframework.data.repository.CrudRepository;

import com.javainterviewpoint.model.Student;

public interface StudentRepository extends CrudRepository<Student, Integer>
{

}

StudentController

package com.javainterviewpoint.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.javainterviewpoint.model.Passport;
import com.javainterviewpoint.model.Student;
import com.javainterviewpoint.repository.StudentRepository;

@RestController
public class StudentController
{
	@Autowired
	public StudentRepository studentRepository;

	@GetMapping("/student/{id}")
	public Student getStudentById(@PathVariable("id") int id)
	{
		Student student = studentRepository.findById(id).get();

		return student;
	}

	@GetMapping("/students")
	public List<Student> getAllStudents()
	{
		List<Student> studentList = new ArrayList<>();
		Iterable<Student> student = studentRepository.findAll();

		for (Student s : student)
		{
			studentList.add(s);
		}

		return studentList;
	}
	
	@PostMapping("/student")
	public Student createStudent(@RequestBody Student student)
	{
		Passport passport = new Passport();
		passport.setId(4);
		passport.setNumber("D123456");
		passport.setStudent(student);
		
		student.setPassport(passport);
		
		studentRepository.save(student);
		
		return getStudentById(student.getId());
	}
	
	@DeleteMapping("/student/{id}")
	public List<Student> deletePassport(@PathVariable("id") int id)
	{
		studentRepository.deleteById(id);

		return getAllStudents();
	}
}

Let’s test our code

Get a particular Student

Place a GET request on the URL http://localhost:8080/student/2

Student GET

Get All Students

Place a GET request on the URL http://localhost:8080/students

Spring Boot JPA One To One Student GET ALL

Create a Student

Place a POST request on the URL http://localhost:8080/student

Pass the Student details in the body of the request.

{
    “id” : 4,
    “name” : “Darcy”
}

Student POST

Delete a Student

Place a DELETE request on the URL http://localhost:8080/student/4

Student DELETE

Hope this article helps you in getting some understanding on Spring Boot JPA One To One. Happy Learning !!

    Download Source Code

Filed Under: Java, Spring, Spring Boot, Spring Tutorial Tagged With: JPA One To One, One To One, Spring Boot JPA, Spring Boot JPA One To One, Spring JPA One To One

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Java Basics

  • JVM Architecture
  • Object in Java
  • Class in Java
  • How to Set Classpath for Java in Windows
  • Components of JDK
  • Decompiling a class file
  • Use of Class.forName in java
  • Use Class.forName in SQL JDBC

Oops Concepts

  • Inheritance in Java
  • Types of Inheritance in Java
  • Single Inheritance in Java
  • Multiple Inheritance in Java
  • Multilevel Inheritance in Java
  • Hierarchical Inheritance in Java
  • Hybrid Inheritance in Java
  • Polymorphism in Java – Method Overloading and Overriding
  • Types of Polymorphism in java
  • Method Overriding in Java
  • Can we Overload static methods in Java
  • Can we Override static methods in Java
  • Java Constructor Overloading
  • Java Method Overloading Example
  • Encapsulation in Java with Example
  • Constructor in Java
  • Constructor in an Interface?
  • Parameterized Constructor in Java
  • Constructor Chaining with example
  • What is the use of a Private Constructors in Java
  • Interface in Java
  • What is Marker Interface
  • Abstract Class in Java

Java Keywords

  • Java this keyword
  • Java super keyword
  • Final Keyword in Java
  • static Keyword in Java
  • Static Import
  • Transient Keyword

Miscellaneous

  • newInstance() method
  • How does Hashmap works internally in Java
  • Java Ternary operator
  • How System.out.println() really work?
  • Autoboxing and Unboxing Examples
  • Serialization and Deserialization in Java with Example
  • Generate SerialVersionUID in Java
  • How to make a class Immutable in Java
  • Differences betwen HashMap and Hashtable
  • Difference between Enumeration and Iterator ?
  • Difference between fail-fast and fail-safe Iterator
  • Difference Between Interface and Abstract Class in Java
  • Difference between equals() and ==
  • Sort Objects in a ArrayList using Java Comparable Interface
  • Sort Objects in a ArrayList using Java Comparator

Follow

  • Coding Utils

Useful Links

  • Spring 4.1.x Documentation
  • Spring 3.2.x Documentation
  • Spring 2.5.x Documentation
  • Java 6 API
  • Java 7 API
  • Java 8 API
  • Java EE 5 Tutorial
  • Java EE 6 Tutorial
  • Java EE 7 Tutorial
  • Maven Repository
  • Hibernate ORM

About JavaInterviewPoint

javainterviewpoint.com is a tech blog dedicated to all Java/J2EE developers and Web Developers. We publish useful tutorials on Java, J2EE and all latest frameworks.

All examples and tutorials posted here are very well tested in our development environment.

Connect with us on Facebook | Privacy Policy | Sitemap

Copyright ©2023 · Java Interview Point - All Rights Are Reserved ·