@OneToOne annotation is used to Connect the table and do the table operations in a bi-directional way. There are plenty of ways to do the Hibernate One-To-One mapping, Let us check it out one by one about Hibernate OneToOne Mapping annotations with Spring Boot Framework.
Pre Requirest to Do the OneToOne Mapping :
- Maven Setup
- Setting Up Data Base
- Create Model Classes
- Create Service Classes
- Create Controller Classes
- Create Repository Class
- Create Main Class
- Application. properties
- Execute the Application
Maven Setup :
Set the necessary required Dependencies in POM.xml. For Data Base Operations we need to set up the Oracle Driver Details. This dependency will import all the necessary jars for Oracle Connection.
com.oracle.database.jdbc ojdbc8 runtime
Since we are using Spring Web for Demo ensure you have the dependencies for Spring Web as well.
Database Setup :
This is one-to-one mapping hence two tables are required, One will act as Main and one is subtable. But note that OneToOne is bidirectional Mapping hence it can be set in both ways for Database Operations.
Create the Tables Person, Address and the Sequence which is used for the Primary Key.
Create Repository Class :
We need to have two repository classes one is to implement the Person Entity another one is to
@Repository
public interface PersonRepository
extends JpaRepository<Persons, Long> {
}
All right. Now begin with Creating the Model Classes.
Create Model Class :
Here are the Logic Begins of OneToOne Mapping. For OneToOne Annotation we need to have the Special configuration apart from the regular model setup
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
private Address address;
So here Address is the Sub Model Class which is annotated with OneToOne with Cascade Type as ALL, Cascading is to maintain the state of the Mapping Parent Entity, If we have the Same columns across both tables we can link the Primary Key of the tables with @PrimaryKeyJoinColumn.
In Sub Model Class, we have to mention the one-to-one linkage details.
@OneToOne(mappedBy = "address",cascade = CascadeType.ALL)
private Person person;
So here we have mentioned the mappedBy which is referring the Address objects of the parent model class Person. So the compiler will find the object mentioned in the mappedBy attributes for entity mapping.
Person.java
package com.example.model;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
@Entity
@Table(name="PERSONS")
public class Persons {
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Id
@GeneratedValue
private Long personId;
public Long getPersonId() {
return personId;
}
public void setPersonId(Long personId) {
this.personId = personId;
}
@Column(name="personName")
private String personName;
@Column(name="personBirthDate")
private Date personBirthDate;
@Override
public String toString() {
return "Employee [personId=" + personId + ", personBirthDate=" + personBirthDate + ", personName=" + personName + "]";
}
public Date getPersonBirthDate() {
return personBirthDate;
}
public void setPersonBirthDate(Date personBirthDate) {
this.personBirthDate = personBirthDate;
}
public String getPersonName() {
return personName;
}
public void setPersonName(String personName) {
this.personName = personName;
}
}
Address.java
package com.example.model;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name="Address")
public class Address {
@OneToOne(mappedBy = "address",cascade = CascadeType.ALL)
private Persons persons;
public Persons getPersons() {
return persons;
}
public void setPersons(Persons persons) {
this.persons = persons;
}
@Id
@GeneratedValue
private Long personId;
public Long getPersonId() {
return personId;
}
public void setPersonId(Long personId) {
this.personId = personId;
}
@Column(name = "address1")
private String address1;
public String getAddress1() {
return address1;
}
public void setAddress1(String address1) {
this.address1 = address1;
}
}
Create Service Class :
Add the Business logic here. Here we are saving the Person and his address.
PersonService.java
package com.example.service;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.controller.Logging;
import com.example.model.Address;
import com.example.model.Persons;
import com.example.repository.EmployeeDetailRepository;
import com.example.repository.PersonRepository;
@Service
public class PersonService {
@Autowired
PersonRepository personRepository;
@Autowired
EmployeeDetailRepository detailRepository;
public List<Persons> getAllPersons()
{
List<Persons> personList = personRepository.findAll();
if(personList.size() > 0) {
return personList;
} else {
return new ArrayList<Persons>();
}
}
public Persons getPersonById(Long id) throws Exception
{
Optional<Persons> person = personRepository.findById(id);
if(person.isPresent()) {
return person.get();
} else {
throw new Exception("Person Record Not Present to Fetch");
}
}
public Persons createOrUpdatePerson(Persons entity) throws Exception
{
Logging.info(" New Record : "+entity.toString());
Optional<Persons> persons = personRepository.findById(entity.getPersonId());
Logging.info("Before inserting New Record");
if(persons.isPresent())
{
Persons newEntity = persons.get();
newEntity.setPersonName(entity.getPersonName());
newEntity.setPersonBirthDate(entity.getPersonBirthDate());
Logging.info("Employee Record Updated ");
Address address = new Address();
address.setAddress1("CHENNAI");
newEntity.setAddress(address);
newEntity = personRepository.save(newEntity); // To update the Record into the table
Logging.info("Person Record Updated ");
return newEntity;
} else {
Address address = new Address();
address.setAddress1("CHENNAI");
entity.setAddress(address);
entity = personRepository.save(entity);
Logging.info("New Record Inserted ");
return entity;
}
}
public void deletePersonById(Long id) throws Exception
{
Optional<Persons> person = personRepository.findById(id);
if(person.isPresent())
{
personRepository.deleteById(id);
} else {
throw new Exception("No Persons available to Delete");
}
}
}
In the above example, we have used save() of the Repository class. And here we are trying to save the records of Parent Entity and subsequently associated entities are saved together.
Create Controller Class :
OneToOneMapping.java
package com.example.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.model.Persons;
import com.example.service.PersonService;
@RestController
@RequestMapping("/persons")
public class OneToOneMapping
{
@Autowired
PersonService service;
@GetMapping
public ResponseEntity<List<Persons>> getAllPersons() {
List<Persons> list = service.getAllPersons();
return new ResponseEntity<List<Persons>>(list, new HttpHeaders(), HttpStatus.OK);
}
@GetMapping("/{id}")
public ResponseEntity<Persons> getEmployeeById(@PathVariable("id") Long id)
throws Exception {
Logging.info("Fetch Request Received :"+id);
Persons entity = service.getPersonById(id);
return new ResponseEntity<Persons>(entity, new HttpHeaders(), HttpStatus.OK);
}
@PostMapping
public ResponseEntity<Persons> createOrUpdateEmployee(@RequestBody Persons persons)
throws Exception {
Logging.info("Inserting Request Received");
Persons updated = service.createOrUpdatePerson(persons);
return new ResponseEntity<Persons>(updated, new HttpHeaders(), HttpStatus.OK);
}
@DeleteMapping("/{id}")
public HttpStatus deletePersonsById(@PathVariable("id") Long id)
throws Exception {
service.deletePersonById(id);
return HttpStatus.FORBIDDEN;
}
}
Create Main Class :
Application.java
public static void main(String[] args) {
LOGGER.info("Spring Boot Application is Running Successfully");
LOGGER.error("THIS IS ERROR BLOCK.....");
SpringApplication.run(Application.class, args);
}