Understanding JPA relationships

February 6, 2026

Modeling database relationships correctly is essential for any backend application. In JPA (Java Persistence API), incorrect or sub-optimal entity mappings can lead to data inconsistency and performance issues.

There are 3 main types of relationships:

  • One-to-One
  • One-to-Many / Many-to-One
  • Many-to-Many

Let's explore these relationships using a simple e-commerce domain model:

  • Customer
  • Address
  • Cart
  • Product

ecommerce-er-diagram

  • One-to-One: A customer has one cart, and a cart belongs to one customer.
  • One-to-Many: A customer has multiple addresses.
  • Many-to-One: Multiple addresses belong to one customer.
  • Many-to-Many: A cart can have multiple products, and a product can be in multiple carts.

Defining the relationships through JPA annotations:

@OneToOne

In a one-to-one relationship, we must decide which table owns the relationship (stores the foreign key). Here, Cart entity (carts table) is the owning side because it has @JoinColumn.

@Entity
@Table(name = "carts")
public class Cart {

@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "customer_id", nullable = false, unique = true)
private Customer customer;
}

The Customer entity is the inverse side. It has a reference to Cart using mappedBy.

@Entity
@Table(name = "customers")
public class Customer {

@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;

@OneToOne(
mappedBy = "customer",
cascade = CascadeType.ALL,
orphanRemoval = true,
fetch = FetchType.LAZY
)
private Cart cart;
}

fetch defaults to EAGER. Set it to LAZY to prevent loading the associated entity unless explicitly accessed.

@OneToMany and @ManyToOne

In one-to-many/many-to-one relationships, the many side is almost always the owning side. In this example, Address entity (addresses table) stores the foreign key from customers table:

@Entity
@Table(name = "addresses")
public class Address {

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "customer_id", nullable = false)
private Customer customer;
}

The inverse side Customer has a reference to the list of addresses.

@Entity
@Table(name = "customers")
public class Customer {

@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;

@OneToMany(
mappedBy = "customer",
cascade = CascadeType.ALL,
orphanRemoval = true,
fetch = FetchType.LAZY
)
private List<Address> addresses = new ArrayList<>();
}

@ManyToMany

Many-to-many relationships require a separate join table to hold the foreign keys from both entities.

@Entity
@Table(name = "carts")
public class Cart {

@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;

@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(
name = "cart_products",
joinColumns = @JoinColumn(name = "cart_id"),
inverseJoinColumns = @JoinColumn(name = "product_id")
)
private List<Product> products = new ArrayList<>();
}

The Product entity is the inverse side with reference to the list of carts:

@Entity
@Table(name = "products")
public class Product {

@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;

@ManyToMany(mappedBy = "products", fetch = FetchType.LAZY)
private List<Cart> carts = new ArrayList<>();
}

Unidirectional vs. Bidirectional Relationships

All the relationships demonstrated above are bidirectional. In JPA, relationships can be navigated in one or both directions:

  • Unidirectional: Only one entity contains a field that refers to the other. For example, if Customer has a Cart field, but Cart does not have a Customer field, the relationship is unidirectional from Customer to Cart.
  • Bidirectional: Both entities have a field that refers to each other. This allows navigation from either side (e.g., finding the cart for a customer, or finding the customer for a cart). In a bidirectional relationship:
    • The owning side is responsible for updating the relationship in the database. It holds the foreign key (using @JoinColumn).
    • The inverse side uses the mappedBy attribute to point to the field in the owning entity that manages the relationship.

References