Spring JPA/Hibernate One to One Relationship – SpringBoot + MySQL

This tutorial will guide you through the steps of configuring Spring JPA One to One relationship with Spring Boot and MySql.

Related articles:
Spring JPA One to Many Relationship
Spring JPA – Many to Many relationship


I. Technologies

– Java 1.8
– Maven 3.3.9
– Spring Tool Suite – Version 3.8.1.RELEASE
– Spring Boot: 1.5.6.RELEASE
– MySql database

II. Practice – Spring JPA One to One Relationship

Step to do
– Create SpringBoot project
– Create Models
– Create JPA Repositories
– Configure Datasource & Spring JPA
– Implement a test Client
– Run & Check results

1. Create SpringBoot project

– Using SpringToolSuite, create a SpringBoot project. Then add needed dependencies:


    org.springframework.boot
    spring-boot-starter-data-jpa

 

    mysql
    mysql-connector-java
    runtime

2. Create Models

Create 2 entities Wife and Husband that having One-to-One relationship:

Spring JPA One to One relationship

2.1 Wife entity
package com.javasampleapproach.jpa.one2one.model;

import javax.persistence.CascadeType;
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;

@Entity
@Table(name="wife")
public class Wife {
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private int id;
	
	private String name;
	
	
	@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name = "husband_id")
	private Husband husband;
	
	public Wife(){}
	
	public Wife(String name){
		this.name = name;
	}
	
	public Wife(String name, Husband husband){
		this.name = name;
		this.husband = husband;
	}
	
	public void setId(int id){
		this.id = id;
	}
	
	public int getId(){
		return this.id;
	}
	
	public void setName(String name){
		this.name = name;
	}
	
	public String getName(){
		return this.name;
	}
	
	public void setHusband(Husband husband){
		this.husband = husband;
	}
	
	public Husband getHusband(){
		return this.husband;
	}
	
	public String toString(){
		String info = String.format("Wife: name = %s has a husband with name = %s", this.name, this.husband.getName());
		return info;
	}
}

2.2 Husband entity
package com.javasampleapproach.jpa.one2one.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name="husband")
public class Husband {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private int id;
	
	private String name;
	
	@OneToOne(mappedBy = "husband")
	private Wife wife;
	
	public Husband(){}
	
	public Husband(String name){
		this.name = name;
	}
	
	public void setId(int id){
		this.id = id;
	}
	
	public int getId(){
		return this.id;
	}
	
	public void setName(String name){
		this.name = name;
	}
	
	public String getName(){
		return this.name;
	}
	
	public void setWife(Wife wife){
		this.wife = wife;
	}
	
	public Wife getWife(){
		return this.wife;
	}
	
	public String toString(){
		String info = String.format("Husband: name = %s has a wife with name = %s", this.name, this.wife.getName());
		return info;
	}
}

@Entity: Specifies that the class is an entity. This annotation is applied to the entity class.
@Id: Specifies the primary key of an entity.
@OneToOne: Defines a single-valued association to another entity that has one-to-one multiplicity.
@JoinColumn: Specifies a column for joining an entity association or element collection. If the JoinColumn annotation itself is defaulted, a single join column is assumed and the default values apply.

3. Create JPA Repositories

Create 2 interface repositories by extends JpaRepository:

WifeRepository.java

package com.javasampleapproach.jpa.one2one.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.javasampleapproach.jpa.one2one.model.Wife;

public interface WifeRepository extends JpaRepository{
}

HusbandRepository.java

package com.javasampleapproach.jpa.one2one.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.javasampleapproach.jpa.one2one.model.Husband;

public interface HusbandRepository extends JpaRepository{
}
4. Configure Datasource & Spring JPA

Open application.properties, configure spring.datasource & spring.jpa:

spring.datasource.url=jdbc:mysql://localhost:3306/testdb
spring.datasource.username=root
spring.datasource.password=12345
  
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
5. Implement a test Client

Use 2 repository: WifeRepository & HusbandRepository:

@Autowired
WifeRepository wifeRepository;
 
@Autowired
HusbandRepository husbandRepository;

Implement 3 functions:
clearData() is used to empty 2 tables wife & husband
saveData() is used to persist entities (Wife & Husband) to database
showData() is used to load all records (Wife & Husband) and show all on console.

Full SourceCode:

package com.javasampleapproach.jpa.one2one;

import java.util.Arrays;
import java.util.List;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.javasampleapproach.jpa.one2one.model.Husband;
import com.javasampleapproach.jpa.one2one.model.Wife;
import com.javasampleapproach.jpa.one2one.repository.HusbandRepository;
import com.javasampleapproach.jpa.one2one.repository.WifeRepository;

@SpringBootApplication
public class SpringJpaOneToOneApplication implements CommandLineRunner{	
	
	@Autowired
    WifeRepository wifeRepository;
     
    @Autowired
    HusbandRepository husbandRepository;

	public static void main(String[] args) {
		SpringApplication.run(SpringJpaOneToOneApplication.class, args);
	}

	@Override
    public void run(String... arg0) throws Exception {
    	deleteData();
    	saveData();
    	showData();
    }
    
    @Transactional
    private void deleteData(){
    	wifeRepository.deleteAll();
        husbandRepository.deleteAll();
    }
    
    @Transactional
    private void saveData(){
    	// Store a wife to DB
        Wife lisa = new Wife("Lisa", new Husband("David"));
        wifeRepository.save(lisa);

        // Store list wifes to DB
        Wife mary = new Wife("Mary", new Husband("Peter"));
        Wife lauren = new Wife("Lauren", new Husband("Phillip"));
        
        wifeRepository.save(Arrays.asList(mary, lauren));
    }
    
    @Transactional
    private void showData(){
    	// get All data
    	List wifes = wifeRepository.findAll();
        List husbands = husbandRepository.findAll();
         
        System.out.println("===================Wifes:==================");
        wifes.forEach(System.out::println);
         
        System.out.println("===================Husbands:==================");
        husbands.forEach(System.out::println);
    }
}
6. Run & Check results

Build & Run the project with SpringBoot App mode.

Hibernate Logs:

Hibernate: select wife0_.id as id1_1_, wife0_.husband_id as husband_3_1_, wife0_.name as name2_1_ from wife wife0_
Hibernate: select husband0_.id as id1_0_0_, husband0_.name as name2_0_0_, wife1_.id as id1_1_1_, wife1_.husband_id as husband_3_1_1_, wife1_.name as name2_1_1_ from husband husband0_ left outer join wife wife1_ on husband0_.id=wife1_.husband_id where husband0_.id=?
Hibernate: select wife0_.id as id1_1_1_, wife0_.husband_id as husband_3_1_1_, wife0_.name as name2_1_1_, husband1_.id as id1_0_0_, husband1_.name as name2_0_0_ from wife wife0_ left outer join husband husband1_ on wife0_.husband_id=husband1_.id where wife0_.husband_id=?
Hibernate: select husband0_.id as id1_0_0_, husband0_.name as name2_0_0_, wife1_.id as id1_1_1_, wife1_.husband_id as husband_3_1_1_, wife1_.name as name2_1_1_ from husband husband0_ left outer join wife wife1_ on husband0_.id=wife1_.husband_id where husband0_.id=?
Hibernate: select wife0_.id as id1_1_1_, wife0_.husband_id as husband_3_1_1_, wife0_.name as name2_1_1_, husband1_.id as id1_0_0_, husband1_.name as name2_0_0_ from wife wife0_ left outer join husband husband1_ on wife0_.husband_id=husband1_.id where wife0_.husband_id=?
Hibernate: select husband0_.id as id1_0_0_, husband0_.name as name2_0_0_, wife1_.id as id1_1_1_, wife1_.husband_id as husband_3_1_1_, wife1_.name as name2_1_1_ from husband husband0_ left outer join wife wife1_ on husband0_.id=wife1_.husband_id where husband0_.id=?
Hibernate: select wife0_.id as id1_1_1_, wife0_.husband_id as husband_3_1_1_, wife0_.name as name2_1_1_, husband1_.id as id1_0_0_, husband1_.name as name2_0_0_ from wife wife0_ left outer join husband husband1_ on wife0_.husband_id=husband1_.id where wife0_.husband_id=?
Hibernate: delete from wife where id=?
Hibernate: delete from husband where id=?
Hibernate: delete from wife where id=?
Hibernate: delete from husband where id=?
Hibernate: delete from wife where id=?
Hibernate: delete from husband where id=?
Hibernate: select husband0_.id as id1_0_, husband0_.name as name2_0_ from husband husband0_
Hibernate: insert into husband (name) values (?)
Hibernate: insert into wife (husband_id, name) values (?, ?)
Hibernate: insert into husband (name) values (?)
Hibernate: insert into wife (husband_id, name) values (?, ?)
Hibernate: insert into husband (name) values (?)
Hibernate: insert into wife (husband_id, name) values (?, ?)
Hibernate: select wife0_.id as id1_1_, wife0_.husband_id as husband_3_1_, wife0_.name as name2_1_ from wife wife0_
Hibernate: select husband0_.id as id1_0_0_, husband0_.name as name2_0_0_, wife1_.id as id1_1_1_, wife1_.husband_id as husband_3_1_1_, wife1_.name as name2_1_1_ from husband husband0_ left outer join wife wife1_ on husband0_.id=wife1_.husband_id where husband0_.id=?
Hibernate: select wife0_.id as id1_1_1_, wife0_.husband_id as husband_3_1_1_, wife0_.name as name2_1_1_, husband1_.id as id1_0_0_, husband1_.name as name2_0_0_ from wife wife0_ left outer join husband husband1_ on wife0_.husband_id=husband1_.id where wife0_.husband_id=?
Hibernate: select husband0_.id as id1_0_0_, husband0_.name as name2_0_0_, wife1_.id as id1_1_1_, wife1_.husband_id as husband_3_1_1_, wife1_.name as name2_1_1_ from husband husband0_ left outer join wife wife1_ on husband0_.id=wife1_.husband_id where husband0_.id=?
Hibernate: select wife0_.id as id1_1_1_, wife0_.husband_id as husband_3_1_1_, wife0_.name as name2_1_1_, husband1_.id as id1_0_0_, husband1_.name as name2_0_0_ from wife wife0_ left outer join husband husband1_ on wife0_.husband_id=husband1_.id where wife0_.husband_id=?
Hibernate: select husband0_.id as id1_0_0_, husband0_.name as name2_0_0_, wife1_.id as id1_1_1_, wife1_.husband_id as husband_3_1_1_, wife1_.name as name2_1_1_ from husband husband0_ left outer join wife wife1_ on husband0_.id=wife1_.husband_id where husband0_.id=?
Hibernate: select wife0_.id as id1_1_1_, wife0_.husband_id as husband_3_1_1_, wife0_.name as name2_1_1_, husband1_.id as id1_0_0_, husband1_.name as name2_0_0_ from wife wife0_ left outer join husband husband1_ on wife0_.husband_id=husband1_.id where wife0_.husband_id=?
Hibernate: select husband0_.id as id1_0_, husband0_.name as name2_0_ from husband husband0_
Hibernate: select wife0_.id as id1_1_1_, wife0_.husband_id as husband_3_1_1_, wife0_.name as name2_1_1_, husband1_.id as id1_0_0_, husband1_.name as name2_0_0_ from wife wife0_ left outer join husband husband1_ on wife0_.husband_id=husband1_.id where wife0_.husband_id=?
Hibernate: select wife0_.id as id1_1_1_, wife0_.husband_id as husband_3_1_1_, wife0_.name as name2_1_1_, husband1_.id as id1_0_0_, husband1_.name as name2_0_0_ from wife wife0_ left outer join husband husband1_ on wife0_.husband_id=husband1_.id where wife0_.husband_id=?
Hibernate: select wife0_.id as id1_1_1_, wife0_.husband_id as husband_3_1_1_, wife0_.name as name2_1_1_, husband1_.id as id1_0_0_, husband1_.name as name2_0_0_ from wife wife0_ left outer join husband husband1_ on wife0_.husband_id=husband1_.id where wife0_.husband_id=?

Application’s Logs:

===================Wifes:==================
Wife: name = Lisa has a husband with name = David
Wife: name = Mary has a husband with name = Peter
Wife: name = Lauren has a husband with name = Phillip
===================Husband:==================
Husband: name = David has a wife with name = Lisa
Husband: name = Peter has a wife with name = Mary
Husband: name = Phillip has a wife with name = Lauren

Database data:

1. wife table

wife

2. husband table

husbands

III. SourceCode

SpringJPAOneToOne



By grokonez | April 25, 2017.

Last updated on June 3, 2018.



Related Posts


4 thoughts on “Spring JPA/Hibernate One to One Relationship – SpringBoot + MySQL”

  1. Hi ,

    Need Help,

    2018-02-02 16:49:18.670  INFO 8920 --- [           main] c.example.demo.BootJpaOneOneApplication  : Starting BootJpaOneOneApplication on IBM679-R90C09PC with PID 8920 (C:\sw\stsNew\BootJpaOneOne\target\classes started by ibm_admin in C:\sw\stsNew\BootJpaOneOne)
    2018-02-02 16:49:18.672  INFO 8920 --- [           main] c.example.demo.BootJpaOneOneApplication  : No active profile set, falling back to default profiles: default
    2018-02-02 16:49:18.712  INFO 8920 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@de3a06f: startup date [Fri Feb 02 16:49:18 IST 2018]; root of context hierarchy
    2018-02-02 16:49:20.098  INFO 8920 --- [           main] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
    2018-02-02 16:49:20.113  INFO 8920 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [
    	name: default
    	...]
    2018-02-02 16:49:20.183  INFO 8920 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate Core {5.0.12.Final}
    2018-02-02 16:49:20.184  INFO 8920 --- [           main] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
    2018-02-02 16:49:20.185  INFO 8920 --- [           main] org.hibernate.cfg.Environment            : HHH000021: Bytecode provider name : javassist
    2018-02-02 16:49:20.231  INFO 8920 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
    2018-02-02 16:49:20.379  INFO 8920 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.Oracle10gDialect
    2018-02-02 16:49:20.538  INFO 8920 --- [           main] o.h.e.j.e.i.LobCreatorBuilderImpl        : HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
    2018-02-02 16:49:20.646  INFO 8920 --- [           main] org.hibernate.tool.hbm2ddl.SchemaUpdate  : HHH000228: Running hbm2ddl schema update
    2018-02-02 16:49:20.699  INFO 8920 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
    2018-02-02 16:49:20.717  WARN 8920 --- [           main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bootJpaOneOneApplication': Unsatisfied dependency expressed through field 'wifeRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.repository.WifeRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    2018-02-02 16:49:20.717  INFO 8920 --- [           main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
    2018-02-02 16:49:20.735  INFO 8920 --- [           main] utoConfigurationReportLoggingInitializer : 
    
    Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
    2018-02-02 16:49:20.815 ERROR 8920 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 
    
    ***************************
    APPLICATION FAILED TO START
    ***************************
    
    Description:
    
    Field wifeRepository in com.example.demo.BootJpaOneOneApplication required a bean of type 'com.example.repository.WifeRepository' that could not be found.
    
    Action:
    
    Consider defining a bean of type 'com.example.repository.WifeRepository' in your configuration.
    
    1. Hi Atul,

      You can see the description:

      Field wifeRepository in com.example.demo.BootJpaOneOneApplication required a bean of type 'com.example.repository.WifeRepository' that could not be found
      

      -> Please double check your implementation of WifeRepository:

      public interface WifeRepository extends JpaRepository{
      

      Then autowired the WifeRepository as below:

      @Autowired
      WifeRepository wifeRepository;
      

      Regards,
      JSA

Got Something To Say:

Your email address will not be published. Required fields are marked *

*