Table of Contents
- Introduction to Entities and Relationships
- Defining Entities in JPA
- Defining Relationships in JPA
- One-to-One Relationship
- One-to-Many Relationship
- Many-to-One Relationship
- Many-to-Many Relationship
- Cascading Operations in Relationships
- Fetching Strategies: Eager vs Lazy Loading
- Conclusion
1. Introduction to Entities and Relationships
In Java, when working with JPA (Java Persistence API), entities represent the objects that map to database tables. The relationships between entities model the relationships between tables in the database. JPA uses annotations to define how entities are related to each other and how they should be persisted in the database.
Entities and their relationships help in structuring your application’s data model, making it easy to perform operations like saving, updating, deleting, and querying data.
Entities
Entities are Java classes that are annotated with @Entity and are used to map to a table in the database. Each entity corresponds to a table in the database, and its fields correspond to columns in that table.
For example, a Customer entity might map to a customer table in the database, with each field in the class representing a column in the table.
2. Defining Entities in JPA
An entity is defined by annotating a class with @Entity and optionally specifying a table name with @Table. Each field in the class typically corresponds to a column in the table.
Here’s an example of how to define a simple entity in JPA:
Example: Defining an Entity
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String department;
// Getters and setters
}
Explanation:
@Entity: Marks the class as an entity.@Id: Marks the field as the primary key.@GeneratedValue: Specifies the strategy for generating primary key values.
In this case, the Employee entity will be mapped to a table called employee (default table name is the class name if not specified), and the id field will act as the primary key.
3. Defining Relationships in JPA
JPA allows us to model relationships between entities using various annotations. The relationships are based on the cardinality between tables (one-to-one, one-to-many, many-to-one, many-to-many).
a. One-to-One Relationship
A one-to-one relationship means that one entity is related to one and only one instance of another entity. This is often used to represent entities that are tightly coupled.
Example:
@Entity
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String street;
private String city;
@OneToOne(mappedBy = "address")
private Employee employee;
// Getters and setters
}
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToOne
@JoinColumn(name = "address_id")
private Address address;
// Getters and setters
}
In the above example:
- An
Employeehas oneAddress, and anAddressis associated with oneEmployee. @OneToOnespecifies the relationship, and@JoinColumnindicates the foreign key in theEmployeetable.- The
mappedByattribute in theAddressentity tells JPA that the relationship is managed by theaddressfield in theEmployeeentity.
b. One-to-Many Relationship
A one-to-many relationship means that one entity can be associated with multiple instances of another entity. This is commonly used to represent a “parent-child” relationship.
Example:
@Entity
public class Department {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "department")
private List<Employee> employees;
// Getters and setters
}
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "department_id")
private Department department;
// Getters and setters
}
In this example:
- A
Departmenthas manyEmployees, but anEmployeebelongs to oneDepartment. @OneToManyrepresents the one-to-many relationship, and themappedByattribute indicates that theEmployeeclass manages the relationship.@ManyToOneis used in theEmployeeclass to indicate the many-to-one side of the relationship.
c. Many-to-One Relationship
A many-to-one relationship means that many entities can be associated with a single instance of another entity. This is essentially the reverse of the one-to-many relationship.
In the previous example, the Employee entity had a many-to-one relationship with the Department entity.
d. Many-to-Many Relationship
A many-to-many relationship means that many instances of one entity can be associated with many instances of another entity.
Example:
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToMany
@JoinTable(
name = "student_course",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id"))
private List<Course> courses;
// Getters and setters
}
@Entity
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@ManyToMany(mappedBy = "courses")
private List<Student> students;
// Getters and setters
}
In this example:
- A
Studentcan enroll in manyCourses, and aCoursecan have manyStudents. @ManyToManydefines the many-to-many relationship. The@JoinTableannotation specifies the join table that links the two entities.mappedByin theCourseentity indicates that the relationship is managed by thecoursesfield in theStudententity.
4. Cascading Operations in Relationships
In JPA, cascading operations allow you to propagate the operations like persist, merge, remove, refresh, etc., from one entity to another related entity.
Example of Cascading Operations:
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "department_id")
private Department department;
// Getters and setters
}
In this example, when an Employee is saved, the associated Department will also be saved due to the cascade = CascadeType.ALL configuration.
Cascade Types:
PERSIST: Propagate the persist operation to the related entity.MERGE: Propagate the merge operation to the related entity.REMOVE: Propagate the remove operation to the related entity.REFRESH: Propagate the refresh operation to the related entity.DETACH: Propagate the detach operation to the related entity.
5. Fetching Strategies: Eager vs Lazy Loading
When working with relationships, JPA allows you to choose how related entities should be fetched from the database. There are two main strategies:
- Eager Loading (
FetchType.EAGER): The related entity is fetched immediately when the parent entity is loaded. - Lazy Loading (
FetchType.LAZY): The related entity is fetched only when it is accessed, i.e., when it is specifically requested in the code.
Example:
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "department_id")
private Department department;
// Getters and setters
}
In this example, the Department entity will not be loaded until the department field is accessed.
6. Conclusion
In this module, we explored how to define entities and their relationships in JPA, which is crucial for building relational data models. Understanding these relationships allows developers to build a clear and efficient mapping between the domain model and the database structure.
We covered:
- Defining entities using the
@Entityannotation. - Modeling relationships such as one-to-one, one-to-many, many-to-one, and many-to-many using appropriate JPA annotations.
- Using cascading operations to propagate changes across related entities.
- Choosing between eager and lazy loading for fetching related entities.
By mastering these concepts, developers can build rich, relational models for their applications while leveraging JPA’s features to handle the complexity of database interactions.

