JPA Annotations Reference Guideline

Table of contents

  1. Abstract
  2. 🔗 @ManyToOne
    1. Properties
  3. 📎 @OneToMany
    1. Properties
  4. 🔗 @OneToOne
    1. Properties
  5. 🔗 @ManyToMany
    1. Properties
  6. 📦 CascadeType Enum
  7. 🧵 FetchType Enum
  8. 🔗 @JoinColumn
  9. 🔗 @JoinTable
  10. 📝 Summary Cheatsheet

Abstract

This reference document provides a comprehensive overview of the relationship annotations in Java Persistence API (JPA), focusing on @ManyToOne and including all other core relationship types: @OneToOne, @OneToMany, and @ManyToMany. Each annotation is explained with its purpose, use cases, and complete property specifications. It details the behaviour and configuration of relationship mappings, including fetch strategies (FetchType), cascading operations (CascadeType), and join management (@JoinColumn, @JoinTable).

Additionally, the document outlines best practices for performance optimization and entity integrity (e.g., using LAZY fetch type, orphan removal, and bidirectional mapping with mappedBy). The guide serves both as a practical tutorial and a quick reference for developers designing relational data models using JPA.


🔗 @ManyToOne

A @ManyToOne relationship maps a many-to-one association: many instances of one entity are associated with one instance of another entity.

@ManyToOne(
    optional = true,
    cascade = {},
    fetch = FetchType.EAGER,
    targetEntity = Class.class
)

Properties

PropertyTypeDefaultDescription
optionalbooleantrueIndicates whether the association is optional (nullable foreign key).
cascadeCascadeType[]{}Specifies operations that should be cascaded to the associated entity.
fetchFetchTypeEAGERDefines whether the association should be eagerly or lazily loaded.
targetEntityClass<?>Default inferredUsed to specify the class of the target entity if not inferred (rarely needed).

Example:

Many Order entities relate to one Customer.

+----------+       FK       +-----------+
|  Order   |--------------->| Customer  |
+----------+                +-----------+
| id       |                | id        |
| customer_id (FK)          | name      |
+----------+                +-----------+
@Entity
public class Order {

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

    @ManyToOne
    private Customer customer;
}
@Entity
public class Customer {

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

    private String name;
}

How it Works:

  • JPA will automatically add a foreign key column (customer_id) in the Order table referencing the Customer’s primary key.
  • You can customize the join column using @JoinColumn.
@ManyToOne
@JoinColumn(name = "customer_id", nullable = false)
private Customer customer;

📎 @OneToMany

@OneToMany One entity has a collection of many instances of another.

@OneToMany(
    mappedBy = "",
    cascade = {},
    fetch = FetchType.LAZY,
    orphanRemoval = false,
    targetEntity = Class.class
)

Properties

PropertyTypeDefaultDescription
mappedByStringRequired (if bidirectional)Name of the field in the owning entity that maps this relationship.
cascadeCascadeType[]{}Cascade operations to children (e.g., persist, remove).
fetchFetchTypeLAZYLazy loading is recommended for collections.
orphanRemovalbooleanfalseAutomatically delete child entities if removed from the collection.
targetEntityClass<?>Default inferredExplicitly declare target class.

Example:

+-----------+                +----------+
| Customer  |<--------------+|  Order   |
+-----------+    1       ∞   +----------+
| id        |                | id       |
| name      |                | customer_id (FK) 
+-----------+                +----------+
  • Customer has many Orders.
  • Order.customer_id is the foreign key.
@Entity
public class Customer {
    @OneToMany(mappedBy = "customer")
    private List<Order> orders;
}

Usually, this is the inverse of a @ManyToOne.


🔗 @OneToOne

@OneToOne(
    mappedBy = "",
    cascade = {},
    fetch = FetchType.EAGER,
    optional = true,
    orphanRemoval = false,
    targetEntity = Class.class
)

Properties

PropertyTypeDefaultDescription
mappedByStringRequired (if bidirectional)Field name on the owning side.
cascadeCascadeType[]{}Cascade operations to the related entity.
fetchFetchTypeEAGERWhether to load immediately or on access.
optionalbooleantrueIf false, a non-nullable foreign key is created.
orphanRemovalbooleanfalseDeletes the associated entity when dereferenced.
targetEntityClass<?>Default inferredUsed when generic types are involved.

Example:

+--------+     1:1      +----------+
|  User  |------------->| Profile  |
+--------+              +----------+
| id     |              | id       |
| profile_id (FK, unique)           |
+--------+              +----------+
  • One User links to one Profile.
  • Foreign key in User, marked UNIQUE to enforce 1:1.

Alternatively, the FK could reside in Profile, depending on ownership.

@Entity
public class User {
    @OneToOne
    @JoinColumn(name = "profile_id")
    private Profile profile;
}

🔗 @ManyToMany

@ManyToMany Each entity in the relationship can relate to many instances of the other.

@ManyToMany(
    mappedBy = "",
    cascade = {},
    fetch = FetchType.LAZY,
    targetEntity = Class.class
)

Properties

PropertyTypeDefaultDescription
mappedByStringRequired (if bidirectional)Specifies the field on the inverse side.
cascadeCascadeType[]{}Cascade actions to the related entities.
fetchFetchTypeLAZYLazy fetching for collections.
targetEntityClass<?>Default inferredTarget class (typically inferred).

Example:

+----------+         +------------------+         +--------+
| Student  |         | student_course   |         | Course |
+----------+         +------------------+         +--------+
| id       |         | student_id (FK)  |<------->| id     |
| name     |<------->| course_id (FK)   |         | title  |
+----------+         +------------------+         +--------+
  • Join table student_course handles many-to-many association.
@Entity
public class Student {
    @ManyToMany
    @JoinTable(
        name = "student_course",
        joinColumns = @JoinColumn(name = "student_id"),
        inverseJoinColumns = @JoinColumn(name = "course_id")
    )
    private Set<Course> courses;
}

📦 CascadeType Enum

Used in: cascade property

public enum CascadeType {
    ALL,
    PERSIST,
    MERGE,
    REMOVE,
    REFRESH,
    DETACH
}
CascadeTypeDescription
ALLApplies all cascade operations.
PERSISTPropagate EntityManager.persist() to the target.
MERGEPropagate EntityManager.merge().
REMOVEPropagate EntityManager.remove().
REFRESHPropagate EntityManager.refresh().
DETACHPropagate EntityManager.detach().

🧵 FetchType Enum

Used in: fetch property

public enum FetchType {
    LAZY,
    EAGER
}
FetchTypeDescription
LAZYAssociation is fetched only when accessed.
EAGERAssociation is fetched immediately.

⚠️ Best Practice: Use LAZY for collections to avoid performance issues.


🔗 @JoinColumn

Used with @ManyToOne, @OneToOne

@JoinColumn(
    name = "column_name",
    referencedColumnName = "id",
    unique = false,
    nullable = true,
    insertable = true,
    updatable = true
)
PropertyTypeDefaultDescription
nameStringInferredName of the foreign key column.
referencedColumnNameString"id"Column in the referenced table.
uniquebooleanfalseMakes the column unique.
nullablebooleantrueWhether the column allows nulls.
insertablebooleantrueWhether the column is insertable.
updatablebooleantrueWhether the column is updatable.

🔗 @JoinTable

Used with @ManyToMany, and optionally @OneToMany

@JoinTable(
    name = "join_table_name",
    joinColumns = @JoinColumn(name = "entity_id"),
    inverseJoinColumns = @JoinColumn(name = "related_entity_id")
)
PropertyTypeDescription
nameStringName of the join table.
joinColumns@JoinColumn[]Defines the foreign key to the owning entity.
inverseJoinColumns@JoinColumn[]Defines the foreign key to the inverse side entity.

📝 Summary Cheatsheet

AnnotationKey PropsDefault FetchRequired if bidirectional
@ManyToOneoptional, cascade, fetchEAGERNo
@OneToManymappedBy, cascade, orphanRemovalLAZYYes
@OneToOnemappedBy, optional, cascadeEAGERYes
@ManyToManymappedBy, cascadeLAZYYes
@JoinColumnname, referencedColumnName, etc.N/ANo
@JoinTablename, joinColumns, inverseJoinColumnsN/ANo