https://loizenai.com/spring-boot-one-to-one-mapping-example/
Tutorial: "Spring Boot One to One Mapping Example - Spring Crud Example using One to One Mapping"
In the tutorial, we show how to expose Crud RestAPIs Post/Get/Put/Delete
to interact with Hibernate Spring JPA One-to-One relationship models using SpringBoot and PostgreSQL database.
- Technologies - Spring Boot One to One Mapping Example:
- Java 8
- Maven 3.5.4
- SpringToolSuite version 3.9.4.RELEASE
- SpringBoot 2.0.4.RELEASE
Overview - Spring Boot One to One Mapping Example
We have 2 modelsStudent
&Contact
withone-to-one
relationship:
[caption id="attachment_4771" align="alignnone" width="504"] Spring Boot One to One - Model Relationships[/caption]
We create a SpringBoot project as below:
[caption id="attachment_4772" align="alignnone" width="701"] Spring Boot Rest Apis Hibernate Spring JPA One To One Postgresql Architecture[/caption]
[caption id="attachment_4773" align="alignnone" width="346"] SpringBoot Project Structure[/caption]
Hibernate JPA configuration for 2 models Student
& Contact
:
-
Student
model ->
@Entity
@Table(name = "students")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "age")
private int age;
@OneToOne(fetch = FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "student")
private Contact contact;
public Student() {}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
// Getters & Setters methods
// ...
- Contact
model:
@Entity
@Table(name = "contacts")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Contact implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "city")
private String city;
@Column(name = "phone")
private String phone;
@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "student_id", nullable = false)
private Student student;
public Contact() {
}
public Contact(String city, String phone) {
this.city = city;
this.phone = phone;
}
// Getters & Setters methods
// ...
We exposes RestAPIs for Post/Get/Put/Delete
Students & Contacts:
- Students ->
-
@GetMapping("/api/students")
: get all Students -
@GetMapping("/api/students/{id}")
: get a Student by ID -
@PostMapping("/api/students")
: post a Student -
@PutMapping("/api/students/{id}")
: update a Student -
@DeleteMapping("/api/students/{id}")
: delete a Student
-
@GetMapping("/contacts")
: get all Contacts -
@GetMapping("/students/{studentId}/contacts")
: get a Contact by Student's ID -
@PostMapping("/students/{studentId}/contacts")
: add a Contact -
@PutMapping("/contacts/{contactId}")
: update a Contact -
@DeleteMapping("/contacts/{contactId}")
: delete a Contact by ID
Create SpringBoot project - Spring Boot One to One Mapping Example
We use SpringToolSuite to create aJava 8
SpringBoot project with below dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
SpringBoot OneToOne Models - Spring Boot One to One Mapping Example
-Student
model ->
code class="language-java"> package com.ozenero.springrestapi.onetoone.model; import java.io.Serializable; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToOne; import javax.persistence.Table; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @Entity @Table(name = "students") @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) public class Student implements Serializable { private static final long serialVersionUID = 1L; @id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "name") private String name; @Column(name = "age") private int age; @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "student") private Contact contact; public Student() {} public Student(String name, int age) { this.name = name; this.age = age; } public void setId(Long id) { this.id = id; } public Long getId() { return this.id; } public void setName(String name) { this.name = name; } public String getName() { return this.name; } public void setAge(int age) { this.age =age; } public int getAge() { return this.age; } }-
Contact
model :
package com.ozenero.springrestapi.onetoone.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
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 com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@Entity
@Table(name = "contacts")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Contact implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "city")
private String city;
@Column(name = "phone")
private String phone;
@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "student_id", nullable = false)
private Student student;
public Contact() {
}
public Contact(String city, String phone) {
this.city = city;
this.phone = phone;
}
public void setId(Long id) {
this.id = id;
}
public Long getId() {
return this.id;
}
public void setCity(String city) {
this.city = city;
}
public String getCity() {
return this.city;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getPhone() {
return this.phone;
}
public void setStudent(Student student) {
this.student = student;
}
public Student getStudent() {
return this.student;
}
}
SpringBoot JPA Repositories - Spring Boot One to One Mapping Example
-StudentRepository
:
package com.ozenero.springrestapi.onetoone.jpa;
import org.springframework.data.jpa.repository.JpaRepository;
import com.ozenero.springrestapi.onetoone.model.Student;
public interface StudentRepository extends JpaRepository {
}
- ContactRepository
model :
package com.ozenero.springrestapi.onetoone.jpa;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import com.ozenero.springrestapi.onetoone.model.Contact;
public interface ContactRepository extends JpaRepository {
List findByStudentId(Long studentId);
}
Add datasource configurations in application.properties
file :
spring.datasource.url=jdbc:postgresql://localhost/testdb
spring.datasource.username=postgres
spring.datasource.password=123
spring.jpa.generate-ddl=true
#spring.jackson.serialization.fail-on-empty-beans=false
Expose SpringBoot Rest APIs - Spring Boot One to One Mapping Example
-StudentController
:
package com.ozenero.springrestapi.onetoone.rest;
import java.util.List;
import java.util.Optional;
import javax.validation.Valid;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ozenero.springrestapi.onetoone.exception.NotFoundException;
import com.ozenero.springrestapi.onetoone.jpa.StudentRepository;
import com.ozenero.springrestapi.onetoone.model.Student;
@RestController
@RequestMapping("/api")
public class StudentController {
@Autowired
private StudentRepository studentRepository;
@GetMapping("/students")
public List getAllStudents() {
return studentRepository.findAll();
}
@GetMapping("/students/{id}")
public Student getStudentByID(@PathVariable Long id) {
Optional optStudent = studentRepository.findById(id);
if(optStudent.isPresent()) {
return optStudent.get();
}else {
throw new NotFoundException("Student not found with id " + id);
}
}
@PostMapping("/students")
public Student createStudent(@Valid @RequestBody Student student) {
return studentRepository.save(student);
}
@PutMapping("/students/{id}")
public Student updateStudent(@PathVariable Long id,
@Valid @RequestBody Student studentUpdated) {
return studentRepository.findById(id)
.map(student -> {
student.setName(studentUpdated.getName());
student.setAge(studentUpdated.getAge());
return studentRepository.save(student);
}).orElseThrow(() -> new NotFoundException("Student not found with id " + id));
}
@DeleteMapping("/students/{id}")
public String deleteStudent(@PathVariable Long id) {
return studentRepository.findById(id)
.map(student -> {
studentRepository.delete(student);
return "Delete Successfully!";
}).orElseThrow(() -> new NotFoundException("Student not found with id " + id));
}
}
- ContactController
:
package com.ozenero.springrestapi.onetoone.rest;
import java.util.List;
import javax.validation.Valid;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ozenero.springrestapi.onetoone.exception.NotFoundException;
import com.ozenero.springrestapi.onetoone.jpa.ContactRepository;
import com.ozenero.springrestapi.onetoone.jpa.StudentRepository;
import com.ozenero.springrestapi.onetoone.model.Contact;
@RestController
@RequestMapping("/api")
public class ContactController {
@Autowired
private ContactRepository contactRepository;
@Autowired
private StudentRepository studentRepository;
@GetMapping("/contacts")
public List getAllContacts(){
return contactRepository.findAll();
}
@GetMapping("/students/{studentId}/contacts")
public Contact getContactByStudentId(@PathVariable Long studentId) {
if(!studentRepository.existsById(studentId)) {
throw new NotFoundException("Student not found!");
}
List contacts = contactRepository.findByStudentId(studentId);
if(contacts.size() > 0) {
return contacts.get(0);
}else {
throw new NotFoundException("Contact not found!");
}
}
@PostMapping("/students/{studentId}/contacts")
public Contact addContact(@PathVariable Long studentId,
@Valid @RequestBody Contact contact) {
return studentRepository.findById(studentId)
.map(student -> {
contact.setStudent(student);
return contactRepository.save(contact);
}).orElseThrow(() -> new NotFoundException("Student not found!"));
}
@PutMapping("/contacts/{contactId}")
public Contact updateContact(@PathVariable Long contactId,
@Valid @RequestBody Contact contactUpdated) {
return contactRepository.findById(contactId)
.map(contact -> {
contact.setCity(contactUpdated.getCity());
contact.setPhone(contactUpdated.getPhone());
return contactRepository.save(contact);
}).orElseThrow(() -> new NotFoundException("Contact not found!"));
}
@DeleteMapping("/contacts/{contactId}")
public String deleteContact(@PathVariable Long contactId) {
return contactRepository.findById(contactId)
.map(contact -> {
contactRepository.delete(contact);
return "Deleted Successfully!";
}).orElseThrow(() -> new NotFoundException("Contact not found!"));
}
}
Run & Check Results
- Run the SpringBoot project with commandlinemvn spring-boot:run
.
2 tables is created in PostgreSQL :
[caption id="attachment_4774" align="alignnone" width="358"] Spring Boot Rest Apis Hibernate Spring Jpa One To One Postgresql Tables Created By JPA[/caption]
- Add Students :
[caption id="attachment_4775" align="alignnone" width="572"] Spring Boot Rest Apis Hibernate Spring JPA One-to-one Postgresql Tables - post a student data[/caption]
- Add Contacts :
[caption id="attachment_4776" align="alignnone" width="566"] Spring Boot Rest Apis Hibernate Spring Jpa One-to-one Postgresql Post a Contact[/caption]
- Update Contact :
[caption id="attachment_4777" align="alignnone" width="569"] Spring Boot Rest Apis Hibernate Spring JPA One-to-one Postgresql Put Contact[/caption]
- Update Student :
[caption id="attachment_4778" align="alignnone" width="588"] Spring Boot Rest Apis Hibernate Spring JPA One-to-one Postgresql Put a student[/caption]
- Get All Students :
[caption id="attachment_4779" align="alignnone" width="332"] Spring Boot Rest Apis Hibernate Spring Jpa one-to-one Postgresql Get All Student[/caption]
- Get All Contacts :
[caption id="attachment_4780" align="alignnone" width="330"] Spring Boot Rest Apis Hibernate Spring Jpa One To One Postgresql Get All Contacts[/caption]
- Delete a Student :
[caption id="attachment_4781" align="alignnone" width="426"] Spring Boot Rest Apis Hibernate Spring JPA One-to-one Postgresql Tables Delete a Student[/caption]
- Delete a Contact :
[caption id="attachment_4782" align="alignnone" width="392"] Spring Boot Rest Apis Hibernate Spring JPA One-to-one Postgresql Tables Delete a Contact[/caption]
Note: PostgreSQL commandline :
PostgreSQL\9.6\bin>psql.exe --username="postgres" -W
: connect to PostgreSQL ->
C:\Program Files\PostgreSQL\9.6\bin>psql.exe --username="postgres" -W
Password for user postgres:
psql (9.6.9)
WARNING: Console code page (437) differs from Windows code page (1252)
8-bit characters might not work correctly. See psql reference
page "Notes for Windows users" for details.
Type "help" for help.
- \l
: List of databases
- \c testdb
: connect to "testdb"
- \d
: List of relations ->
testdb=# \d List of relations Schema | Name | Type | Owner --------+-----------------+----------+---------- public | contacts | table | postgres public | contacts_id_seq | sequence | postgres public | students | table | postgres public | students_id_seq | sequence | postgres (4 rows)
-
testdb=# \q
: ExitRead More
Related posts:
Top comments (0)