Difference between FetchType LAZY and EAGER in Java Persistence API?
I am a newbie to Java Persistence API and Hibernate.
What is the difference between FetchType.LAZY
and FetchType.EAGER
in Java Persistence API?
Sometimes you have two entities and there's a relationship between them. For example, you might have an entity called University
and another entity called Student
and a University might have many Students:
The University entity might have some basic properties such as id, name, address, etc. as well as a collection property called students that returns the list of students for a given university:
public class University {
private String id;
private String name;
private String address;
private List<Student> students;
// setters and getters
}
Now when you load a University from the database, JPA loads its id, name, and address fields for you. But you have two options for how students should be loaded:
- To load it together with the rest of the fields (i.e. eagerly), or
- To load it on-demand (i.e. lazily) when you call the university's
getStudents()
method.
When a university has many students it is not efficient to load all of its students together with it, especially when they are not needed and in suchlike cases you can declare that you want students to be loaded when they are actually needed. This is called lazy loading.
Here's an example, where students
is explicitly marked to be loaded eagerly:
@Entity
public class University {
@Id
private String id;
private String name;
private String address;
@OneToMany(fetch = FetchType.EAGER)
private List<Student> students;
// etc.
}
And here's an example where students
is explicitly marked to be loaded lazily:
@Entity
public class University {
@Id
private String id;
private String name;
private String address;
@OneToMany(fetch = FetchType.LAZY)
private List<Student> students;
// etc.
}
Basically,
LAZY = fetch when needed
EAGER = fetch immediately
EAGER
loading of collections means that they are fetched fully at the time their parent is fetched. So if you have Course
and it has List<Student>
, all the students are fetched from the database at the time the Course
is fetched.
LAZY
on the other hand means that the contents of the List
are fetched only when you try to access them. For example, by calling course.getStudents().iterator()
. Calling any access method on the List
will initiate a call to the database to retrieve the elements. This is implemented by creating a Proxy around the List
(or Set
). So for your lazy collections, the concrete types are not ArrayList
and HashSet
, but PersistentSet
and PersistentList
(or PersistentBag
)