03 JPA Associations
Relationships
Relationships between entities can be unidirectional or bidirectional. In a unidirectional relationship, one entity has a reference to another entity. In a bidirectional relationship, both entities have a reference to each other.
Unidirectional Relationships
There are four types of unidirectional relationships in JPA:
- One-to-One (a person has one address)
- One-to-Many (a customer has many orders)
- Many-to-One (many books are published by one publisher)
- Many-to-Many (a student can enroll in many modules, and a module can have many students)
classDiagram
Person "1" --> "0..1" Address
Customer "1" --> "*" Order
Book "*" --> "1" Publisher
Student "*" --> "*" Module
Bidirectional Relationships
In a bidirectional relationship, both entities have a reference to each other. One side will be the owner of the relationship, and the other side will be the inverse side. The owner side is responsible for the relationship and is the side that updates the database. The inverse side is the side that does not update the database.
In the following list, the owning side is bold.
- One-to-One
- Many-to-Many/One-to-Many
- Many-to-Many
classDiagram
Person "1" <--> "0..1" Address
Book "*" <--> "1" Publisher
Student "*" <--> "*" Module
Mapping Annotations
JPA provides annotations to define the relationships between entities. The most common annotations are:
@OneToOne: Create a one-to-one relationship between two entities.@OneToMany: Create a one-to-many relationship between two entities.@ManyToOne: Create a many-to-one relationship between two entities.@ManyToMany: Create a many-to-many relationship between two entities.@JoinColumn: Define the join column for an association.@JoinTable: Define the join table for a many-to-many relationship.
Attributes on Associations
targetEntity: The target entity class if it cannot be inferred from the property type.mappedBy: The field that owns the relationship.cascade: The operations to cascade.fetch: The fetch type.optional: If the relationship is optional (nullable).orphanRemoval: If orphan removal is enabled. If enabled, has same effect asCascadeType.REMOVE.
| Attribute | @OneToOne | @OneToMany | @ManyToOne | @ManyToMany |
|---|---|---|---|---|
targetEntity | X | X | X | X |
mappedBy | X | X | X | |
cascade | X | X | X | X |
fetch | X | X | X | X |
optional | X | X | ||
orphanRemoval | X | X |
Cascade Operations
Cascade operations define how changes to one entity propagate to another entity. The most common cascade operations are:
CascadeType.ALL: Apply all operations to the related entity.CascadeType.PERSIST: Apply the persist operation to the associated entities.CascadeType.MERGE: Apply the merge operation to the associated entities.CascadeType.REMOVE: Associated entities are removed when the entity is removed. Should only be used on@OneToOneand@OneToMany.CascadeType.REFRESH: Apply the refresh operation to the associated entities.CascadeType.DETACH: Apply the detach operation to the associated entities.
Fetch Types
Fetch types define how related entities are loaded from the database. The most common fetch types are:
FetchType.EAGER: Load the related entity immediately.- Default for
@OneToOneand@ManyToOne. - Default for
@Basicand@ElementCollection.
- Default for
FetchType.LAZY: Load the related entity when it is accessed.- Default for
@OneToManyand@ManyToMany.
- Default for