[英]Does Spring Data JPA ignore @Fetch annotations?
I have the following JPA Mapping (getters and setters out for brevity purposes, the DDL also gets generated from the code which may/may not play a role): 我有以下JPA映射(为了简洁起见,使用getter和setter,DDL也从可能/可能不起作用的代码中生成):
Expense 费用
@Entity
public class Expense {
@Id
@GeneratedValue
private Long id;
private String name;
private Long amount;
private Boolean monthly;
@OneToOne
@JoinColumn(name = "category")
@Fetch(FetchMode.JOIN)
private Category category;
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<Label> labels = new ArrayList<>();
//constructor, getters and setters...
}
Category 类别
@Entity
public class Category {
@Id
private String name;
//constructor, getters and setters...
}
Label 标签
@Entity
public class Label {
@Id
private String name;
//constructor, getters and setters...
}
Usage with JpaRepository JpaRepository的用法
So I am using a JpaRepository that looks like this: 因此,我使用的JpaRepository如下所示:
public interface ExpensesRepository extends JpaRepository<Expense, Long> {
@Query("SELECT e FROM Expense e LEFT JOIN FETCH e.category")
List<Expense> findAllExpensesExploded();
}
When I use the default findAll() method of the JpaRepository, I get a n+1 select problem : 当我使用JpaRepository的默认findAll()方法时,出现一个n + 1选择问题 :
2017-01-03 19:35:22.665 DEBUG 26040 --- [nio-8080-exec-1] org.hibernate.SQL : select expense0_.id as id1_1_, expense0_.amount as amount2_1_, expense0_.category_name as category5_1_, expense0_.monthly as monthly3_1_, expense0_.name as name4_1_ from expense expense0_
2017-01-03 19:35:22.673 DEBUG 26040 --- [nio-8080-exec-1] org.hibernate.SQL : select category0_.name as name1_0_0_ from category category0_ where category0_.name=?
2017-01-03 19:35:22.674 TRACE 26040 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [Rent]
2017-01-03 19:35:22.682 DEBUG 26040 --- [nio-8080-exec-1] org.hibernate.SQL : select category0_.name as name1_0_0_ from category category0_ where category0_.name=?
2017-01-03 19:35:22.683 TRACE 26040 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [Insurance]
However, when I use my own findAllExpensesExploded() method I get a single SQL query: 但是,当我使用自己的findAllExpensesExploded()方法时,会得到一个SQL查询:
2017-01-03 19:35:22.691 DEBUG 26040 --- [nio-8080-exec-1] org.hibernate.SQL : select expense0_.id as id1_1_0_, category1_.name as name1_0_1_, expense0_.amount as amount2_1_0_, expense0_.category_name as category5_1_0_, expense0_.monthly as monthly3_1_0_, expense0_.name as name4_1_0_ from expense expense0_ left outer join category category1_ on expense0_.category_name=category1_.name
My expectation was for both findAll() and findAllExpensesExploded() to be executed with a single SQL query . 我的期望是findAll()和findAllExpensesExploded()都可以通过单个SQL查询执行。
The Default fetch mode is lazy. 默认提取模式是惰性的。 It's always a good practice to use
@NamedEntityGraph
and @EntityGraph
annotations when working with Spring Data JPA.You can go through this 它总是使用一个很好的做法
@NamedEntityGraph
和@EntityGraph
使用Spring数据JPA.You工作可以顺利通过时,注释本
whether the default findAll() should only be used for simple entities? (where simple is defined as no associations).
Fetch Mode - LAZY will only fire for primary table. 提取模式-LAZY仅针对主表触发。 If in the code you call any other method that has a parent table dependency then it will fire Fetch Mode - SELECT.
如果在代码中调用具有父表依赖项的任何其他方法,则它将触发“访存模式-SELECT”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.