In this post, we will see One to One Bidirectional Mapping Example In Hibernate/JPA Using Spring Boot and Oracle.
- We have two entity Book.java and Story .java. Book and Story entity have one to one bidirectional relationship that means the Book entity has a Story entity and the Story entity also contains Book entity.
- We will not create a table, let’s hibernate do this job.
- After running this example we will be able to save Book as well Story in oracle database using postman.
Note – Default Fetch type in case of below annotations.
@OneToOne – Default fetch type is EAGER.
@OneToMany – Default fetch type is LAZY.
@ManyToOne – Default fetch type is EAGER.
@ManyToMany – Default fetch type is LAZY.
After running the below example we will have database entry like below.
Let’s see a complete example of One to One Bidirectional Mapping In Hibernate/JPA Spring Boot from scratch.
Prerequisites –
- JDK 1.8
- Oracle 10g
- Eclipse
- maven
- postman
Open eclipse and create maven project, Don’t forget to check ‘Create a simple project (skip)’click on next. Fill all details(GroupId – onetoonehibernatejpa, ArtifactId – onetoonehibernatejpa and name – onetoonehibernatejpa) and click on finish. Keep packaging as the jar.
Replace the pom.xml with the below code.
<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>onetoonehibernatejpa</groupId> <artifactId>onetoonehibernatejpa</artifactId> <version>0.0.1-SNAPSHOT</version> <name>onetoonehibernatejpa</name> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.2.RELEASE</version> </parent> <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>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.2.0.3</version> </dependency> </dependencies> <build> <finalName>${project.artifactId}</finalName> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <fork>true</fork> <executable>C:\Program Files\Java\jdk1.8.0_131\bin\javac.exe</executable> </configuration> </plugin> </plugins> </build> </project>
Note – In pom.xml we have defined javac.exe path in configuration tag. You need to change accordingly i.e where you have installed JDK.
If you see any error for oracle dependency then follow these steps.
Let maven download all necessary jar. Once it is done we will able to see the maven dependency folder which contains different jar files.
We are good now. We can start writing our controller classes, ServiceImpl and Repository. The directory structure of the application looks as below.
Define entity class i.e Book.java and Story.java.
Book.java
package com.onetoonehibernatejpa.entity; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToOne; import com.fasterxml.jackson.annotation.JsonManagedReference; @Entity public class Book { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int bookId; @Column(name = "book_name") private String bookName; @OneToOne(cascade = CascadeType.ALL, mappedBy = "book") @JsonManagedReference private Story story; public Story getStory() { return story; } public void setStory(Story story) { this.story = story; } public int getBookId() { return bookId; } public void setBookId(int bookId) { this.bookId = bookId; } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } }
Story.java
package com.onetoonehibernatejpa.entity; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToOne; import com.fasterxml.jackson.annotation.JsonBackReference; @Entity public class Story { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int storyId; @Column(name = "story_name") private String storyName; @OneToOne(cascade = CascadeType.ALL) @JoinColumn(name = "book_id") @JsonBackReference private Book book; public int getStoryId() { return storyId; } public void setStoryId(int storyId) { this.storyId = storyId; } public String getStoryName() { return storyName; } public void setStoryName(String storyName) { this.storyName = storyName; } public Book getBook() { return book; } public void setBook(Book book) { this.book = book; } }
Define the repository interface extending CrudRepository.
BookRepository.java
package com.onetoonehibernatejpa.repository; import java.io.Serializable; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; import com.onetoonehibernatejpa.entity.Book; @Repository public interface BookRepository extends CrudRepository<Book,Serializable> { public Book findByBookId(int bookId); }
Define service interface i.e BookService.java for One to One Bidirectional In Hibernate/JPA Spring Boot example
package com.onetoonehibernatejpa.service; import org.springframework.stereotype.Component; import com.onetoonehibernatejpa.entity.Book; @Component public interface BookService { public Book saveBook(Book book); public Book findByBookId(int bookId); }
Define service implementation class.
BookServiceImpl.java
package com.onetoonehibernatejpa.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.onetoonehibernatejpa.entity.Book; import com.onetoonehibernatejpa.entity.Story; import com.onetoonehibernatejpa.repository.BookRepository; import com.onetoonehibernatejpa.service.BookService; @Service("bookServiceImpl") public class BookServiceImpl implements BookService { @Autowired private BookRepository bookRepository; public Book saveBook(Book book) { Story story = book.getStory(); story.setBook(book); book = bookRepository.save(book); return book; } public Book findByBookId(int bookId) { Book book = bookRepository.findByBookId(bookId); return book; } }
Note – See here more about @Component, @Controller, @Service and @Repository annotations here.
Define the controller class or endpoint.
BookController.java
package com.onetoonehibernatejpa.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import com.onetoonehibernatejpa.entity.Book; import com.onetoonehibernatejpa.service.BookService; @RestController @RequestMapping(value = "/book") public class BookController { @Autowired private BookService bookService; @RequestMapping(value = "/savebook",method = RequestMethod.POST) @ResponseBody public Book saveBook(@RequestBody Book book) { Book bookResponse = bookService.saveBook(book); return bookResponse; } @RequestMapping(value = "/{bookId}",method = RequestMethod.GET) @ResponseBody public Book getBookDetails(@PathVariable int bookId) { Book bookResponse = bookService.findByBookId(bookId); return bookResponse; } }
Note – See more details about @Controller and RestController here.
Define the JpaConfig.java
package com.onetoonehibernatejpa.config; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @Configuration @EnableJpaRepositories(basePackages = "com.onetoonehibernatejpa.repository") public class JpaConfig { }
Note – See more details about @Configuration annotations here.
Define the SpringMain.java
package com.onetoonehibernatejpa.main; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.ComponentScan; @SpringBootApplication @ComponentScan(basePackages="com.onetoonehibernatejpa.*") @EntityScan("com.onetoonehibernatejpa.*") public class SpringMain { public static void main(String[] args) { SpringApplication.run(SpringMain.class, args); } }
Note – See more details about @ComponentScan here.
And finally, we have an application.properties file where we have database details.
application.properties
# Connection url for the database spring.datasource.url=jdbc:oracle:thin:@localhost:1521:XE spring.datasource.username=SYSTEM spring.datasource.password=oracle2 spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver # Show or not log for each sql query spring.jpa.show-sql = true spring.jpa.hibernate.ddl-auto =update spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.Oracle10gDialect server.port = 9091
We are almost done. Just build the project once running the main method. Open git bash or cmd and Run mvn clean install.
Let’s deploy the application running SpringMain class as a java application.
Now we will prepare json data and will try save in database.
Sample request JSON data-
{ "bookName":"rich dad poor dad", "story":{ "storyName":"motivational story" } }
Let’s test the save url.
Let’s check the database. One to One Bidirectional In Hibernate/JPA Spring Boot.
Yes, we have record in the book as well as story table. Did you notice book_id is the column in the story table is a foreign key? This is the primary key for the book table.
Now test the get URL i.e http://localhost:9091/book/1
Let’s see in the below diagram which will give us a brief about flow.
That’s all about One to One Bidirectional In Hibernate/JPA Spring Boot. If you feel any problem to run the application leave a comment.
Other association mapping example in hibernate using Spring Boot and oracle.
One to One Mapping Annotation Example in Hibernate/JPA using Spring Boot and Oracle.
One To Many Mapping Annotation Example In Hibernate/JPA Using Spring Boot And Oracle.
One To Many Bidirectional Mapping In Hibernate/JPA Annotation Example Using Spring Boot and Oracle
Many To One Unidirectional Mapping In Hibernate/JPA Annotation Example Using Spring Boot and Oracle.
Many To Many Mapping Annotation Example In Hibernate/JPA Using Spring Boot And Oracle.
Inheritance Mapping in Hibernate Using Spring Boot and Oracle.
- Hibernate Table Per Concrete Class Spring Boot.
- Hibernate Table Per Subclass Inheritance Spring Boot.
- Hibernate Single Table Inheritance using Spring Boot.
Spring Data JPA tutorials.
- Spring Data JPA greater than Example
- Spring Data JPA less than Example
- Spring Data JPA IsNull Example Using Spring Boot
- Spring Data findById() Vs getOne()
- Spring Data JPA CrudRepository findById()
- Spring Data JPA JpaRepository getOne()
- Spring Data CrudRepository saveAll() and findAll().
- Spring Data CrudRepository existsById()
- Spring Data JPA delete() vs deleteInBatch()
- Spring Data JPA deleteAll() Vs deleteAllInBatch()
- Spring Data JPA JpaRepository deleteAllInBatch()
- Spring Data JPA deleteInBatch() Example
- Spring Data JPA JpaRepository saveAndFlush() Example
- Spring Data JPA CrudRepository count() Example
- Spring Data JPA CrudRepository delete() and deleteAll()
- Spring Data JPA CrudRepository deleteById() Example
- CrudRepository findAllById() Example Using Spring Boot
- Spring Data CrudRepository save() Method.
- Sorting in Spring Data JPA using Spring Boot.
- Spring Data JPA example using spring boot.
- Spring Data JPA and its benefit.
@OneToOne docs.
Summary – We have seen One to One Bidirectional Mapping in Hibernate/JPA using Spring Boot and Oracle. In one to one mapping one entity associated with another entity Bidirectionally.