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 )
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@GeneratedValue ( strategy = GenerationType. IDENTITY )
@Column ( name = "id" , nullable = false , updatable = false , unique = true )
@Column ( name = "uid" , unique = true , nullable= false , updatable= false )
@JsonIgnoreProperties ( value= { "address" })
@OneToOne ( fetch=FetchType. LAZY , cascade=CascadeType. ALL )
@JoinColumn ( name= "address_id" , updatable = false , nullable= false , unique= true )
// TODO Auto-generated constructor stub
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.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 )
public class Address implements Serializable {
private static final long serialVersionUID = 1L;
@GeneratedValue ( strategy = GenerationType. IDENTITY )
@Column ( name = "id" , nullable = false , updatable = false , unique = true )
@Column ( name = "street2" )
@Column ( name = "zipcode" )
// TODO Auto-generated constructor stub
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
}
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 )
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@GeneratedValue ( strategy = GenerationType. IDENTITY )
@Column ( name = "id" , nullable = false , updatable = false , unique = true )
@Column ( name = "uid" , unique = true , nullable= false , updatable= false )
@JsonIgnoreProperties ( value= { "user" })
@OneToOne ( fetch=FetchType. LAZY , cascade=CascadeType. ALL , mappedBy= "user" )
// TODO Auto-generated constructor stub
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
}
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 )
public class Laptop implements Serializable {
private static final long serialVersionUID = 1L;
@ Column ( name = "id" , nullable = false , updatable = false , unique = true )
@ Column ( name = "serial_number" )
private String serialNumber;
@ Column ( name = "model_number" )
private String modelNumber;
@ JsonIgnoreProperties ( value= { "laptop" })
@ JoinColumn ( name= "user_id" )
// TODO Auto-generated constructor stub
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
}
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