One-To-Many relationship is used widely in database operations. For exampel a user can have multiple cars or a user can have multiple computer screens to work with.
Our example is a user can have multiple orders as in a restaurant order. Let’s suppose you are asked to develop a pizza restaurant application where customers can order online. a User can have multiple orders.
One-To-Many Bidirectional Relationship
// On the parent side which is the User class. @OneToMany(mappedBy="user",cascade=CascadeType.ALL,fetch=FetchType.EAGER) private Set<Order> orders;
// On the child side which is the Order class. @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "user_id", nullable=false) private User user;
package com.lovemesomecoding.user; import java.io.Serializable; import java.util.HashSet; import java.util.Set; 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.OneToMany; 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.order.Order; @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"}) @OneToMany(mappedBy = "user", cascade=CascadeType.ALL, fetch=FetchType.EAGER) private Set<Order> orders; public User() { super(); // TODO Auto-generated constructor stub } // getters and setters public void addOrder(Order order) { if(this.orders == null){ this.orders = new HashSet<>(); } this.orders.add(order); } }
package com.lovemesomecoding.order; import java.io.Serializable; import java.time.LocalDateTime; import java.util.Date; 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.ManyToOne; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; import org.hibernate.annotations.CreationTimestamp; 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 = "user_order") public class Order 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 = "coupon_code") private String couponCode; @Column(name = "discount") private Double discount; @Column(name = "total_amount") private Double totalAmount; @Column(name = "payment_method_id") private Long paymentMethodId; @CreationTimestamp @Column(name = "created_at") private Date createdAt; @JsonIgnoreProperties(value= {"orders"}) @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "user_id", nullable=false) private User user; public Order() { super(); // TODO Auto-generated constructor stub } // setters and getters }
One-To-Many Unidirectional Relationship
It depends on the needs you might have. If you need to access orders from the User class then you use this below:
// On the parent side(User class) @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER) private Set<Order> orders;
or if you need to access a user from the Order class then your use this below:
// On the child side(Order class) @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "user_id", nullable=false) private User user;
My preference and what I recommend is to use bidirectional. Using unidirectional will slow down your system as it creates an extra join for the
Use mappedBy on the @OneToMany otherwise, it will create a reference or associative table.
@JoinColumn is always on the owing side or the child side of the relationship.