了解弹簧数据如何处理@EntityGraph

2022-09-03 06:37:02

(我为这个问题做了一个SSCCE

我有2个简单的实体:和。 与默认抓取策略(eager )有关系。EmployeeCompanyEmployee@ManyToOneCompany

我希望能够在不更改中定义的获取策略的情况下加载,因为我只需要为一个用例执行此操作。EmployeeCompanyEmployee

JPA的实体图似乎就是为了这个目的。

所以我在类上定义了一个:@NamedEntityGraphEmployee

@Entity
@NamedEntityGraph(name = "employeeOnly")
public class Employee {

  @Id
  private Integer id;
  private String name;
  private String surname;
  @ManyToOne
  private Company company;

  //Getters & Setters

像这样:EmployeeRepository

public interface EmployeeRepository extends CrudRepository<Employee, Integer> {

  @EntityGraph(value = "employeeOnly", type = EntityGraph.EntityGraphType.FETCH)
  List<Employee> findByCompanyId(Integer companyId);

}

尽管使用了 ,但我可以在日志中看到 仍然通过休眠加载:@EntityGraphCompany

2016-11-07 23:16:08.738 DEBUG 1029 --- [nio-8080-exec-2] org.hibernate.SQL                        : select employee0_.id as id1_1_, employee0_.company_id as company_4_1_, employee0_.name as name2_1_, employee0_.surname as surname3_1_ from employee employee0_ left outer join company company1_ on employee0_.company_id=company1_.id where company1_.id=?
2016-11-07 23:16:08.744 DEBUG 1029 --- [nio-8080-exec-2] org.hibernate.SQL                        : select company0_.id as id1_0_0_, company0_.name as name2_0_0_ from company company0_ where company0_.id=?

为什么?如何避免这种情况?


答案 1

Hibernate 不支持将非 lazy 属性处理为 lazy,即使使用实体图也是如此。有一个问题:HHH-8776,但现在已经修复了。

以前,目前唯一的解决方案是使关联变得懒惰。


答案 2

修改的答案

根据规范,默认情况下,的读取类型是。但即使通过我们设置:@ManyToOneEAGER

@ManyToOne(fetch = FetchType.LAZY)
private Company company;

你会得到同样的结果。问题在于 spring-data-jpa 为你创建 HQL/JPQL 的方式。因此,添加不起作用是不够的。要解决此问题,请在存储库中使用注释:@ManyToOne(fetch = FetchType.LAZY)@ManyToOne(fetch = FetchType.LAZY)@Query

员工.java

@ManyToOne(fetch = FetchType.LAZY)
private Company company;

员工存储库.java

@Query("from Employee e where e.company.id = :companyId")
List<Employee> findByCompanyIdUsingQuery(@Param("companyId") Integer companyId);

在测试中,这是由您的生成的 SQL(生成左外连接):loadByCompanyId()

select employee0_.id as id1_1_, employee0_.company_id as company_4_1_, employee0_.name as name2_1_, employee0_.surname as surname3_1_ from employee employee0_ left outer join company company1_ on employee0_.company_id=company1_.id where company1_.id=?

这是通过使用注释的方法生成的SQL:@Query

select employee0_.id as id1_1_, employee0_.company_id as company_4_1_, employee0_.name as name2_1_, employee0_.surname as surname3_1_ from employee employee0_ where employee0_.company_id=?

您可以检查我的存储库中的最新代码。

呵呵。


推荐