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.