Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@OneToMany(EAGER) vs @LazyCollection(FALSE)&OneToMany(LAZY)

What is difference between codes?

@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(mappedBy = "siteesTypeSite", cascade = CascadeType.ALL,fetch = FetchType.LAZY)
public Set<Sites> getSitees() {
    return sitees;
}

and

@OneToMany(mappedBy = "siteesTypeSite", cascade = CascadeType.ALL,fetch = FetchType.EAGER)
public Set<Sites> getSitees() {
    return sitees;
}

As for me both of them makes similar result, but second case is more cleaner. If i mistook correct me please.

like image 479
Sergii Avatar asked Jul 07 '16 09:07

Sergii


1 Answers

The main difference between the annotations is that @OneToMany is a pure JPA annotation. Whereas @LazyCollection is Hibernate specific.

So if you want your code to be portable across various JPA providers you should use JPA annotations.

Update

To explain between those two annotation, consider the OneToMany relationship between Department -> Employee

Case 1:

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
@JoinColumn(name = "DEPARTMENT_ID")
private List<Employee> employees = new ArrayList<>();

if you fetch a Department object from the db using :

entityManager.find(Department.class, 1L);

following query gets fired to fetch the data

SELECT department0_.DEPARTMENT_ID AS DEPARTMENT_ID1_0_0_,
  department0_.DEPARTMENT_NAME    AS DEPARTMENT_NAME2_0_0_,
  department0_.LOCATION           AS LOCATION3_0_0_,
  employees1_.DEPARTMENT_ID       AS DEPARTMENT_ID3_1_1_,
  employees1_.EMPLOYEE_ID         AS EMPLOYEE_ID1_1_1_,
  employees1_.EMPLOYEE_ID         AS EMPLOYEE_ID1_1_2_,
  employees1_.DEPARTMENT_ID       AS DEPARTMENT_ID3_1_2_,
  employees1_.EMPLOYEE_NAME       AS EMPLOYEE_NAME2_1_2_
FROM DEPARTMENT department0_
LEFT OUTER JOIN EMPLOYEE employees1_
ON department0_.DEPARTMENT_ID   =employees1_.DEPARTMENT_ID
WHERE department0_.DEPARTMENT_ID=?

so it means it will fetch all the data in a single query at once.

Case 2:

@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY, orphanRemoval = true)
@JoinColumn(name = "DEPARTMENT_ID")
private List<Employee> employees = new ArrayList<>();

similary if you fetch a Department object from the db using :

entityManager.find(Department.class, 1L);

following queries gets fired to fetch the data :

SELECT department0_.DEPARTMENT_ID AS DEPARTMENT_ID1_0_0_,
  department0_.DEPARTMENT_NAME    AS DEPARTMENT_NAME2_0_0_,
  department0_.LOCATION           AS LOCATION3_0_0_
FROM DEPARTMENT department0_
WHERE department0_.DEPARTMENT_ID=?

SELECT employees0_.DEPARTMENT_ID AS DEPARTMENT_ID3_1_0_,
  employees0_.EMPLOYEE_ID        AS EMPLOYEE_ID1_1_0_,
  employees0_.EMPLOYEE_ID        AS EMPLOYEE_ID1_1_1_,
  employees0_.DEPARTMENT_ID      AS DEPARTMENT_ID3_1_1_,
  employees0_.EMPLOYEE_NAME      AS EMPLOYEE_NAME2_1_1_
FROM EMPLOYEE employees0_
WHERE employees0_.DEPARTMENT_ID=?

So to summarize, in first case since the FetchType is EAGER Employees are fetched eagerly along with Department in a single JOIN query.

And,

In second case, Employees are fetched with Department but since the FetchType is LAZY a seperate query will be fired to fetch Employees. And if you remove @LazyCollection(LazyCollectionOption.FALSE) Employees wont be fetched at all until you access Employees on Department instance.

like image 69
eatSleepCode Avatar answered Sep 23 '22 21:09

eatSleepCode