注解的主要区别在于@OneToMany是一个纯JPA注解。而@LazyCollection 是特定于 Hibernate 的。
因此,如果您希望您的代码可以跨各种 JPA 提供程序移植,您应该使用 JPA 注释。
更新
要解释这两个注释之间的关系,请考虑Department -> Employee 之间的OneToMany 关系
案例 1:
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
@JoinColumn(name = "DEPARTMENT_ID")
private List<Employee> employees = new ArrayList<>();
如果您使用以下方法从数据库中获取Department 对象:
entityManager.find(Department.class, 1L);
触发以下查询以获取数据
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=?
这意味着它将一次获取单个查询中的所有数据。
案例 2:
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY, orphanRemoval = true)
@JoinColumn(name = "DEPARTMENT_ID")
private List<Employee> employees = new ArrayList<>();
如果您使用以下方法从数据库中获取 Department 对象,则类似:
entityManager.find(Department.class, 1L);
以下查询被触发以获取数据:
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=?
总结一下,在第一种情况下,由于FetchType 是EAGER Employees 在单个JOIN 查询中与Department 一起被急切地获取。
还有,
在第二种情况下,Employees 与 Department 一起获取,但由于 FetchType 是 LAZY,将触发单独的查询以获取 Employees。如果你删除 @LazyCollection(LazyCollectionOption.FALSE) Employees 将不会被获取,直到你访问 Department 实例上的 Employees。