Spring Data One To One Mapping

One to One defines as one entity is related to a single instance of another entity.

Example of One to One
1. a user is related to a single address(home address).
2. a post has a post details table
3. a stock has a stock details table
4. an employee has a single computer

Let’s suppose we have to build a user management system. We are asked to create a user table, an address table, and a laptop table.

Unidirectional Relationship
In a unidirectional relationship, only one entity has a relationship field or property that refers to the other entity.
The user will have a one to one relationship with a home address. This relationship is a unidirectional since the User class will reference the Address class but the Address class does not have a reference to the User class.

package com.lovemesomecoding.user;

import java.io.Serializable;

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

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.lovemesomecoding.address.Address;

@JsonInclude(value = Include.NON_NULL)
@Entity
@Table(name = "user")
public class User implements Serializable {

	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "id", nullable = false, updatable = false, unique = true)
	private Long id;
	
	@Column(name = "uid", unique = true, nullable=false, updatable=false)
	private String uid;

	@Column(name = "name")
	private String name;

	@Column(name = "email")
	private String email;

	@Column(name = "age")
	private int age;
	
	@JsonIgnoreProperties(value= {"address"})
	@OneToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
	@JoinColumn(name="address_id", updatable = false, nullable=false, unique=true)
	private Address address;

	public User() {
		super();
		// TODO Auto-generated constructor stub
	}

	// setters and getters
}
package com.lovemesomecoding.address;

import java.io.Serializable;

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

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;

@JsonInclude(value = Include.NON_NULL)
@Entity
@Table(name = "address")
public class Address implements Serializable {

	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "id", nullable = false, updatable = false, unique = true)
	private Long id;
	
	@Column(name = "street")
	private String street;

	@Column(name = "street2")
	private String street2;

	@Column(name = "city")
	private String city;
	
	@Column(name = "state")
	private String state;

	@Column(name = "zipcode")
	private String zip;
	
	public Address() {
		super();
		// TODO Auto-generated constructor stub
	}

	// setters and getters

}

Bidirectional Relationship
In a bidirectional relationship, each entity has a relationship field or property that refers to the other entity. The User class has a reference to the Laptop class and vice versa.

package com.lovemesomecoding.user;

import java.io.Serializable;

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

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.lovemesomecoding.address.Address;
import com.lovemesomecoding.laptop.Laptop;

@JsonInclude(value = Include.NON_NULL)
@Entity
@Table(name = "user")
public class User implements Serializable {

	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "id", nullable = false, updatable = false, unique = true)
	private Long id;
	
	@Column(name = "uid", unique = true, nullable=false, updatable=false)
	private String uid;

	@Column(name = "name")
	private String name;

	@Column(name = "email")
	private String email;

	@Column(name = "age")
	private int age;
	
	@JsonIgnoreProperties(value= {"user"})
	@OneToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL, mappedBy="user")
	private Laptop laptop;

	public User() {
		super();
		// TODO Auto-generated constructor stub
	}

	// setters and getters
}

Note here that I used the @MapsId annotation so that the Laptop class will use the User class id value as its primary key value. This is the most efficient way of mapping a one to one relationship.

package com.lovemesomecoding.laptop;

import java.io.Serializable;
import java.time.LocalDate;

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.MapsId;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.lovemesomecoding.user.User;

@JsonInclude(value = Include.NON_NULL)
@Entity
@Table(name = "laptop")
public class Laptop implements Serializable {

	private static final long serialVersionUID = 1L;

	@Id
	@Column(name = "id", nullable = false, updatable = false, unique = true)
	private Long id;
	
	@Column(name = "type")
	private String type;
	
	@Column(name = "serial_number")
	private String serialNumber;
	
	@Column(name = "model_number")
	private String modelNumber;
	
	@Column(name = "year")
	private LocalDate year;
	
	@JsonIgnoreProperties(value= {"laptop"})
	@OneToOne
	@JoinColumn(name="user_id")
	@MapsId
	private User user;

	public Laptop() {
		super();
		// TODO Auto-generated constructor stub
	}

	// setters and getters
}

Check out the source code in Github




Subscribe To Our Newsletter
You will receive our latest post and tutorial.
Thank you for subscribing!

required
required


Leave a Reply

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