springdatajpa是否忽略@fetch注解?

pgx2nnw8  于 2021-07-12  发布在  Java
关注(0)|答案(1)|浏览(334)

我有以下jpaMap(getter和setter出于简洁的目的,ddl也从代码中生成,这些代码可能/可能不起作用):
费用

@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...
}

类别

@Entity
public class Category {

@Id
private String name;

//constructor, getters and setters...
}

标签

@Entity
public class Label {

@Id
private String name;
//constructor, getters and setters...

}

与jparepository一起使用
所以我用的是一个类似于这样的jparepository:

public interface ExpensesRepository extends JpaRepository<Expense, Long> {

    @Query("SELECT e FROM Expense e LEFT JOIN FETCH e.category")
    List<Expense> findAllExpensesExploded();
}

当我使用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]

但是,当我使用自己的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

我的期望是findall()和findallexpensesexploded()都用一个sql查询执行。
我的查询之所以有效,是因为我似乎正确地构造了它
但是为什么findall()不能与给定的Map注解一起工作呢?spring数据是否可能忽略了@fetch注解?
另外一个似乎合理的问题是,默认的findall()是否应该只用于简单的实体(其中简单定义为无关联)。

zujrkrfu

zujrkrfu1#

默认的获取模式是lazy。这总是一个很好的做法 @NamedEntityGraph 以及 @EntityGraph 使用spring数据jpa时的注解

whether the default findAll() should only be used for simple entities? (where simple is defined as no associations).

获取模式-lazy将只对主表激发。如果在代码中调用任何其他具有父表依赖关系的方法,那么它将触发fetch mode-select。

相关问题