🚀 Limited-Time Offer! Get 90% OFF on My Udemy Courses Grab the Deal 🎯

Spring Boot and Hibernate One-to-One CRUD REST API Tutorial

🎓 Top 15 Udemy Courses (80-90% Discount): My Udemy Courses - Ramesh Fadatare — All my Udemy courses are real-time and project oriented courses.

▶️ Subscribe to My YouTube Channel (178K+ subscribers): Java Guides on YouTube

▶️ For AI, ChatGPT, Web, Tech, and Generative AI, subscribe to another channel: Ramesh Fadatare on YouTube

In this tutorial, we will demonstrate how to set up a one-to-one relationship between User and UserProfile entities using Spring Boot and Hibernate, and expose CRUD operations through a REST API.

Prerequisites

  1. Java Development Kit (JDK) 11 or higher: Ensure JDK is installed and configured on your system.
  2. Integrated Development Environment (IDE): IntelliJ IDEA, Eclipse, or any other IDE.
  3. Maven: Ensure Maven is installed and configured on your system.

Step 1: Create a Spring Boot Project

  1. Open your IDE and create a new Spring Boot project.
  2. Use Spring Initializr or manually create the pom.xml file to include Spring Boot and other required dependencies.
<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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>spring-boot-one-to-one-example</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.1.0</version> <relativePath/> </parent> <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>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 

Explanation

  • spring-boot-starter-data-jpa: Includes Spring Data JPA with Hibernate.
  • spring-boot-starter-web: Includes Spring MVC for building web applications.
  • h2: An in-memory database for testing purposes.

Step 2: Configure the Application Properties

Configure the application.properties file to set up the H2 database.

spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password= spring.jpa.database-platform=org.hibernate.dialect.H2Dialect spring.h2.console.enabled=true spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true 

Step 3: Create the User Entity Class

Create a package named com.example.entity and a class named User.

package com.example.entity; import jakarta.persistence.*; @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username; private String email; @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false) private UserProfile userProfile; public User() {} public User(String username, String email) { this.username = username; this.email = email; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public UserProfile getUserProfile() { return userProfile; } public void setUserProfile(UserProfile userProfile) { if (userProfile == null) { if (this.userProfile != null) { this.userProfile.setUser(null); } } else { userProfile.setUser(this); } this.userProfile = userProfile; } @Override public String toString() { return "User{id=" + id + ", username='" + username + '\'' + ", email='" + email + '\'' + '}'; } } 

Explanation

  • @Entity: Marks the class as an entity.
  • @Id: Marks the field as the primary key.
  • @GeneratedValue: Specifies the strategy for generating values for the primary key.
  • @OneToOne: Defines a one-to-one relationship with the UserProfile entity.
  • mappedBy: Specifies the field in the UserProfile entity that owns the relationship.
  • cascade: Specifies the cascade operations.
  • fetch: Specifies the fetch type (lazy loading).
  • optional: Indicates whether the relationship is optional.

Step 4: Create the UserProfile Entity Class

Create a class named UserProfile in the same package.

package com.example.entity; import jakarta.persistence.*; @Entity public class UserProfile { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String address; private String phoneNumber; @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") private User user; public UserProfile() {} public UserProfile(String address, String phoneNumber) { this.address = address; this.phoneNumber = phoneNumber; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } @Override public String toString() { return "UserProfile{id=" + id + ", address='" + address + '\'' + ", phoneNumber='" + phoneNumber + '\'' + '}'; } } 

Explanation

  • @Entity: Marks the class as an entity.
  • @Id: Marks the field as the primary key.
  • @GeneratedValue: Specifies the strategy for generating values for the primary key.
  • @OneToOne: Defines a one-to-one relationship with the User entity.
  • @JoinColumn: Specifies the foreign key column.

Step 5: Create Repository Interfaces

Create a package named com.example.repository and interfaces for User and UserProfile.

package com.example.repository; import com.example.entity.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface UserRepository extends JpaRepository<User, Long> {} 
package com.example.repository; import com.example.entity.UserProfile; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface UserProfileRepository extends JpaRepository<UserProfile, Long> {} 

Step 6: Create Service Classes

Create a package named com.example.service and service classes for User and UserProfile.

package com.example.service; import com.example.entity.User; import com.example.entity.UserProfile; import com.example.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserService { @Autowired private UserRepository userRepository; public User save(User user) { return userRepository.save(user); } public List<User> findAll() { return userRepository.findAll(); } public User findById(Long id) { return userRepository.findById(id).orElse(null); } public void deleteById(Long id) { userRepository.deleteById(id); } } 
package com.example.service; import com.example.entity.UserProfile; import com.example.repository.UserProfileRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserProfileService { @Autowired private UserProfileRepository userProfileRepository; public UserProfile save(UserProfile userProfile) { return userProfileRepository.save(userProfile); } public List<UserProfile> findAll() { return userProfileRepository.findAll(); } public UserProfile findById(Long id) { return userProfileRepository.findById(id).orElse(null); } public void deleteById(Long id) { userProfileRepository.deleteById(id); } } 

Step 7: Create Controller Classes

Create a package named com.example.controller and controller classes for User and UserProfile.

package com.example .controller; import com.example.entity.User; import com.example.entity.UserProfile; import com.example.service.UserService; import com.example.service.UserProfileService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/users") public class UserController { @Autowired private UserService userService; @Autowired private UserProfileService userProfileService; @PostMapping public User createUser(@RequestBody User user) { if (user.getUserProfile() != null) { user.getUserProfile().setUser(user); } return userService.save(user); } @GetMapping public List<User> getAllUsers() { return userService.findAll(); } @GetMapping("/{id}") public User getUserById(@PathVariable Long id) { return userService.findById(id); } @DeleteMapping("/{id}") public void deleteUser(@PathVariable Long id) { userService.deleteById(id); } @PostMapping("/{userId}/profile") public User addUserProfile(@PathVariable Long userId, @RequestBody UserProfile userProfile) { User user = userService.findById(userId); if (user != null) { userProfile.setUser(user); user.setUserProfile(userProfile); userService.save(user); return user; } return null; } @DeleteMapping("/{userId}/profile") public User removeUserProfile(@PathVariable Long userId) { User user = userService.findById(userId); if (user != null && user.getUserProfile() != null) { userProfileService.deleteById(user.getUserProfile().getId()); user.setUserProfile(null); return userService.save(user); } return null; } } 
package com.example.controller; import com.example.entity.UserProfile; import com.example.service.UserProfileService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/profiles") public class UserProfileController { @Autowired private UserProfileService userProfileService; @PostMapping public UserProfile createUserProfile(@RequestBody UserProfile userProfile) { return userProfileService.save(userProfile); } @GetMapping public List<UserProfile> getAllUserProfiles() { return userProfileService.findAll(); } @GetMapping("/{id}") public UserProfile getUserProfileById(@PathVariable Long id) { return userProfileService.findById(id); } @DeleteMapping("/{id}") public void deleteUserProfile(@PathVariable Long id) { userProfileService.deleteById(id); } } 

Step 8: Create Main Application Class

Create a package named com.example and a class named SpringBootOneToOneExampleApplication.

package com.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringBootOneToOneExampleApplication { public static void main(String[] args) { SpringApplication.run(SpringBootOneToOneExampleApplication.class, args); } } 

Step 9: Run the Application

  1. Run the SpringBootOneToOneExampleApplication class.
  2. Use an API client (e.g., Postman) or a web browser to test the endpoints.

Testing the Endpoints

  1. Create a User:

    • URL: POST /users
    • Body:
      { "username": "john_doe", "email": "john@example.com", "userProfile": { "address": "123 Main St", "phoneNumber": "123-456-7890" } } 
  2. Create User Profile:

    • URL: POST /profiles
    • Body:
      { "address": "123 Main St", "phoneNumber": "123-456-7890" } 
  3. Get All Users:

    • URL: GET /users
  4. Get User by ID:

    • URL: GET /users/{id}
  5. Delete User by ID:

    • URL: DELETE /users/{id}
  6. Add User Profile to User:

    • URL: POST /users/{userId}/profile
    • Body:
      { "address": "123 Main St", "phoneNumber": "123-456-7890" } 
  7. Remove User Profile from User:

    • URL: DELETE /users/{userId}/profile
  8. Get All User Profiles:

    • URL: GET /profiles
  9. Get User Profile by ID:

    • URL: GET /profiles/{id}
  10. Delete User Profile by ID:

  • URL: DELETE /profiles/{id}

Conclusion

You have successfully created an example using Spring Boot and Hibernate to demonstrate a one-to-one relationship between User and UserProfile entities. This tutorial covered setting up a Spring Boot project, configuring Hibernate, creating entity classes with a one-to-one relationship, and performing CRUD operations through RESTful endpoints.

Comments

Spring Boot 3 Paid Course Published for Free
on my Java Guides YouTube Channel

Subscribe to my YouTube Channel (165K+ subscribers):
Java Guides Channel

Top 10 My Udemy Courses with Huge Discount:
Udemy Courses - Ramesh Fadatare