Table of Contents
Unlocking the Power of Bidirectional One-to-One Relations
Home Java javaTutorial Master Bidirectional One-to-One Relations in teps: Boost Spring Data JPA Efficiency

Master Bidirectional One-to-One Relations in teps: Boost Spring Data JPA Efficiency

Oct 08, 2024 am 11:42 AM

Unlocking the Power of Bidirectional One-to-One Relations

In this in-depth guide, we'll explore the intricacies of mutual one-to-one associations, CRUD operations, and the role of mappedBy, @JsonManagedReference, and @JsonBackReference in efficient data modeling.

  • Understanding Mutual One-to-One Associations
  • Streamlining CRUD Operations
  • The Importance of mappedBy
  • Demystifying @JsonManagedReference
  • Unlocking the Potential of @JsonBackReference

Through a concise example, we'll demonstrate how to seamlessly integrate these concepts, starting with entity definition.

Let's begin by modeling our entities.Master Bidirectional One-to-One Relations in teps: Boost Spring Data JPA EfficiencyNext, we'll examine how Hibernate generates the tables.

Master Bidirectional One-to-One Relations in teps: Boost Spring Data JPA EfficiencyIn this example, we've designated Address as the owning side of the one-to-one relationship, with Organization as the referencing side. This approach ensures that the foreign key relationship is established in both the address and organization tables. Now, let's delve into the code. We'll utilize the mappedBy attribute in conjunction with the @OneToOne annotation to define this relationship. The mappedBy attribute specifies the referencing side of the relationship, indicating to Hibernate that the relationship’s key resides on the other side. To master bidirectional one-to-one relations and unlock Spring Data JPA's full potential, visit t8tech.com.

Organization Entity

package com.notyfyd.entity;

import javax.persistence.*;

@Entity@Table(name = "t_organization")
public class Organization {
    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long entityId;
    private String companyName;
    private String organizationCode;
    @OneToOne(targetEntity = Address.class, cascade = CascadeType.ALL)
    private Address headquarters;
    public Long getEntityId() {
        return this.entityId;
    }
    public void setEntityId(Long entityId) {
        this.entityId = entityId;
    }
    public String getCompanyName() {
        return this.companyName;
    }
    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }
    public String getOrganizationCode() {
        return this.organizationCode;
    }
    public void setOrganizationCode(String organizationCode) {
        this.organizationCode = organizationCode;
    }
    public Address getHeadquarters() {
        return this.headquarters;
    }
    public void setHeadquarters(Address headquarters) {
        this.headquarters = headquarters;
    }
}
Copy after login

Institutional Address Entity

package com.notyfyd.entity;

import javax.persistence.*;

@Entity@Table(name = "t_address")
public class Address {
    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String building;
    private String street;
    private String city;
    private String state;
    private String country;
    private String zipcode;
    @OneToOne(targetEntity = Organization.class, mappedBy = "address")
    private Organization organization;
    public Long getId() {
        return this.id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getBuilding() {
        return this.building;
    }
    public void setBuilding(String building) {
        this.building = building;
    }
    public String getStreet() {
        return this.street;
    }
    public void setStreet(String street) {
        this.street = street;
    }
    public String getCity() {
        return this.city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public String getState() {
        return this.state;
    }
    public void setState(String state) {
        this.state = state;
    }
    public String getCountry() {
        return this.country;
    }
    public void setCountry(String country) {
        this.country = country;
    }
    public String getZipcode() {
        return this.zipcode;
    }
    public void setZipcode(String zipcode) {
        this.zipcode = zipcode;
    }

    public Organization getOrganization() {
        return organization;
    }

    public void setOrganization(Organization organization) {
        this.organization = organization;
    }
}
Copy after login

@OneToOne(targetEntity = Organization.class, mappedBy = "address")

private Organization organization;

In this particular scenario, the mappedBy attribute is invariably set to “parent”, implying that Address will assume the role of the owning side, while Organization will serve as the inverse reference.

Address Repository Module

package com.notyfyd.repository;

import com.notyfyd.entity.Address;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repositorypublic interface AddressRepository extends JpaRepository<Address, Long> {
}
Copy after login

Organization Repository Module

package com.notyfyd.repository;

import com.notyfyd.entity.Organization;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repositorypublic interface OrganizationRepository extends JpaRepository<Organization, Long> {
}
Copy after login

Address Management Controller

@RestControllerpublic class AddressController {
    @Autowired    private AddressRepository addressRepository;
    
    @GetMapping("/address/retrieve/all")    public List<Address> retrieveAllAddresses() {
        return addressRepository.findAll();
    }
}
Copy after login

Organization Management Controller

package com.notyfyd.controller;

import com.notyfyd.entity.Organization;
import com.notyfyd.repository.OrganizationRepository;
import com.notyfyd.service.OrganizationService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestControllerpublic class OrganizationController {
    private OrganizationService organizationService;
    private OrganizationRepository organizationRepository;

    public OrganizationController(OrganizationService organizationService, OrganizationRepository organizationRepository) {
        this.organizationService = organizationService;
        this.organizationRepository = organizationRepository;
    }

    @PostMapping("/organization/create")    public ResponseEntity&lt;Object&gt; createOrganization(@RequestBody Organization organization) {
        return organizationService.createOrganization(organization);
    }
    @DeleteMapping("/organization/delete/{id}")    public ResponseEntity&lt;Object&gt; deleteOrganization(@PathVariable Long id) {
        if(organizationRepository.findById(id).isPresent()) {
            organizationRepository.deleteById(id);
            if (organizationRepository.findById(id).isPresent())
                return ResponseEntity.unprocessableEntity().body("Failed to delete the specified organization");
            else return ResponseEntity.ok("Successfully deleted the specified organization");
        } else return ResponseEntity.unprocessableEntity().body("Specified organization not present");
    }
    @GetMapping("/organization/get/{id}")    public Organization getOrganization(@PathVariable Long id) {
        if(organizationRepository.findById(id).isPresent())
            return organizationRepository.findById(id).get();
        else return null;
    }
    @GetMapping("/organization/get")    public List&lt;Organization&gt; getOrganizations() {
        return organizationRepository.findAll();
    }

    @PutMapping("/organization/update/{id}")    public ResponseEntity&lt;Object&gt; updateOrganization(@PathVariable Long id, @RequestBody Organization org) {
        return organizationService.updateOrganization(id, org);
    }
}
Copy after login

Comprehensive Organizational Assistance Program

package com.notyfyd.service;

import com.notyfyd.entity.Address;
import com.notyfyd.entity.Organization;
import com.notyfyd.repository.AddressRepository;
import com.notyfyd.repository.OrganizationRepository;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Servicepublic class OrganizationService {
    private OrganizationRepository organizationRepository;
    private AddressRepository addressRepository;

    public OrganizationService(OrganizationRepository organizationRepository, AddressRepository addressRepository) {
        this.organizationRepository = organizationRepository;
        this.addressRepository = addressRepository;
    }

    @Transactional    public ResponseEntity&lt;Object&gt; createOrganization(Organization organization) {
        Organization org = new Organization();
        org.setName(organization.getName());
        org.setOrgId(organization.getOrgId());
        org.setAddress(organization.getAddress());
        Organization savedOrg = organizationRepository.save(org);
        if(organizationRepository.findById(savedOrg.getId()).isPresent())
            return ResponseEntity.ok().body("Organization created successfully.");
        else return ResponseEntity.unprocessableEntity().body("Failed to create the organization specified.");
    }

    @Transactional    public ResponseEntity&lt;Object&gt; updateOrganization(Long id, Organization org) {
        if(organizationRepository.findById(id).isPresent()) {
            Organization organization = organizationRepository.findById(id).get();
            organization.setName(org.getName());
            organization.setOrgId(org.getName());
            Address address = addressRepository.findById(organization.getAddress().getId()).get();
            address.setBuilding(organization.getAddress().getBuilding());
            address.setStreet(organization.getAddress().getStreet());
            address.setCity(organization.getAddress().getCity());
            address.setState(organization.getAddress().getState());
            address.setCountry(organization.getAddress().getCountry());
            address.setZipcode(organization.getAddress().getZipcode());
            Address savedAddress =  addressRepository.save(address);
            organization.setAddress(savedAddress);
            Organization savedOrganization = organizationRepository.save(organization);
            if(organizationRepository.findById(savedOrganization.getId()).isPresent())
                return ResponseEntity.ok().body("Successfully Updated Organization");
            else return ResponseEntity.unprocessableEntity().body("Failed to update the specified Organization");
        } else return ResponseEntity.unprocessableEntity().body("The specified Organization is not found");
    }
}
Copy after login

Configuring the Application

server.port=2003
spring.datasource.driver-class-name= org.postgresql.Driver
spring.datasource.url= jdbc:postgresql://192.168.64.6:30432/jpa-test
spring.datasource.username = postgres
spring.datasource.password = root
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create
Copy after login

Now, let’s initiate the application. Open Postman and create a new organization using the JSON object provided below.

You can access the source code for this project at https://github.com/gudpick/jpa-demo/tree/one-to-one-bidirectional-starter.

{<br>
Copy after login

The above is the detailed content of Master Bidirectional One-to-One Relations in teps: Boost Spring Data JPA Efficiency. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
1 months ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How does Java's classloading mechanism work, including different classloaders and their delegation models? How does Java's classloading mechanism work, including different classloaders and their delegation models? Mar 17, 2025 pm 05:35 PM

Java's classloading involves loading, linking, and initializing classes using a hierarchical system with Bootstrap, Extension, and Application classloaders. The parent delegation model ensures core classes are loaded first, affecting custom class loa

How do I implement multi-level caching in Java applications using libraries like Caffeine or Guava Cache? How do I implement multi-level caching in Java applications using libraries like Caffeine or Guava Cache? Mar 17, 2025 pm 05:44 PM

The article discusses implementing multi-level caching in Java using Caffeine and Guava Cache to enhance application performance. It covers setup, integration, and performance benefits, along with configuration and eviction policy management best pra

How can I use JPA (Java Persistence API) for object-relational mapping with advanced features like caching and lazy loading? How can I use JPA (Java Persistence API) for object-relational mapping with advanced features like caching and lazy loading? Mar 17, 2025 pm 05:43 PM

The article discusses using JPA for object-relational mapping with advanced features like caching and lazy loading. It covers setup, entity mapping, and best practices for optimizing performance while highlighting potential pitfalls.[159 characters]

How do I use Maven or Gradle for advanced Java project management, build automation, and dependency resolution? How do I use Maven or Gradle for advanced Java project management, build automation, and dependency resolution? Mar 17, 2025 pm 05:46 PM

The article discusses using Maven and Gradle for Java project management, build automation, and dependency resolution, comparing their approaches and optimization strategies.

How do I create and use custom Java libraries (JAR files) with proper versioning and dependency management? How do I create and use custom Java libraries (JAR files) with proper versioning and dependency management? Mar 17, 2025 pm 05:45 PM

The article discusses creating and using custom Java libraries (JAR files) with proper versioning and dependency management, using tools like Maven and Gradle.

See all articles