【问题标题】:@OneToMany(EAGER) vs @LazyCollection(FALSE)&OneToMany(LAZY)@OneToMany(EAGER) 与 @LazyCollection(FALSE)&OneToMany(LAZY)
【发布时间】:2016-11-09 13:53:43
【问题描述】:

代码有什么区别?

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

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

就我而言,他们都得到了相似的结果,但第二种情况更干净。如果我错了,请纠正我。

【问题讨论】:

标签: java hibernate lazy-initialization


【解决方案1】:

注解的主要区别在于@OneToMany是一个纯JPA注解。而@LazyCollection 是特定于 Hibernate 的。

因此,如果您希望您的代码可以跨各种 JPA 提供程序移植,您应该使用 JPA 注释。

更新

要解释这两个注释之间的关系,请考虑Department -&gt; 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=?

总结一下,在第一种情况下,由于FetchTypeEAGER Employees 在单个JOIN 查询中与Department 一起被急切地获取。

还有,

在第二种情况下,EmployeesDepartment 一起获取,但由于 FetchTypeLAZY,将触发单独的查询以获取 Employees。如果你删除 @LazyCollection(LazyCollectionOption.FALSE) Employees 将不会被获取,直到你访问 Department 实例上的 Employees

【讨论】:

  • 这是问题的答案吗? 代码之间有什么区别?
  • 在什么情况下你需要区别? @Sergii
  • 开玩笑吗?如果您在程序中应用第一个代码并在程序中应用其他部分。应该是什么结果? @Sergii 就我而言,他们俩的结果相似
  • 我认为第一种情况是过度工程的例子。但我需要一些确认(我以前从未使用过 LazyCollection,谁知道呢,它可能会提供具有更好性能的进程或其他东西)。我在文章中找到的第一个代码部分,但出现了疑问。
  • 我无法在我的项目中获取导入注释@LazyCollection 我正在运行 Wildfly 12.0。这种方式运行:D:\Software\wildfly-12.0.0.Final\bin Standalone -b 0.0.0.0 --debug --server-config=standalone.xml -Dee8.preview.mode=true
猜你喜欢
  • 2021-08-21
  • 2013-05-13
  • 2014-11-17
  • 2019-01-25
  • 1970-01-01
  • 1970-01-01
  • 2016-12-10
  • 2021-07-11
  • 2016-09-06
相关资源
最近更新 更多