Difference Between Fetchtype Lazy and Eager in Java Persistence API

Difference between FetchType LAZY and 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:

A university has many students

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:

  1. To load it together with the rest of the fields (i.e. eagerly), or
  2. 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.
}

Getting same value on Fetctype Lazy and Eager

There is no change in JSON with the FetchType - and should not. The fetch type is a strategy of loading data from a database.

With EAGER user and address loads at the same time, with one SQL call:

@GetMapping(value = "/users")
public List<User> getUsers() {

List<User> users = userRepository.findAll(); // users and addresses was loaded
return users;
}

With LAZY, address will not be loaded while you don't read them. But, when you return users from a controller, JSON mapper read address property, so it will be loaded with one SQL call per user:

@GetMapping(value = "/users")
public List<User> getUsers() {

List<User> users = userRepository.findAll(); // users was loaded
return users; // addresses was loaded for each user one by one
}

And the second question. There are many ways. See JsonView, for example.

Does EAGER FetchType populates to its children

Nothing about the documentation of FetchType implies any behavior with regards to an associated entity's own FetchType. Note even the description of LAZY (this is from the documentation of the JPA specification):

"The LAZY strategy is a hint to the persistence provider runtime that data should be fetched lazily when it is first accessed. The implementation is permitted to eagerly fetch data for which the LAZY strategy hint has been specified."

So as a side note, in general LAZY may not be guaranteed depending on the implementation provider.

Hibernate (the most popular JPA implementation) will lazily fetch superChildren, so the FetchType of Parent#children will not matter. I haven't tried with other implementations but I highly doubt it will differ.

difference between @Fetch(FetchMode.SELECT) and fetch = FetchType.LAZY

FetchType.LAZY: refers to when Hibernate will fetch the association and entities.

@Fetch(FetchMode.SELECT): refers to how Hibernate will fetch the association and entities.



Related Topics



Leave a reply



Submit