spring data JPA忽略查询方法上的fetchmode

Posted

技术标签:

【中文标题】spring data JPA忽略查询方法上的fetchmode【英文标题】:spring data JPA ignoring fetchmode on query methods 【发布时间】:2019-07-11 01:16:43 【问题描述】:

我有具有传递关系的实体。因此,实体 A 映射到实体 B 的 OneToMany,而实体 B 映射到实体 C 的 OneToMany。 实体 A 有一个属性 userID,它不是主键,我需要从数据库中获取用户 ID 的所有记录。由于要求,我想急切地获取A和B的子记录。我已经使用 FetchMode join 注释了实体,并且我的存储库有一个方法 findByUserId(int userId)。 我正在使用带有hibernate的spring data JPA作为底层ORM。 执行上述查询方法会触发多个查询,但我预计只会触发一个带有连接的查询。

我已经尝试过 EntityGraphs,使用 NamedQuery 注释了我的存储库方法,尝试了双向映射实体 ManyToOne,但似乎没有任何效果。

@Entity
@Table(name = "A_Master")
public class EntityA
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    private int userId;

    @OneToMany(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "FK_reservationId")
    @Fetch(FetchMode.JOIN)
    private List<EntityB> bEntities= new ArrayList<>();



@Entity
@Table(name = "Entity_B")
public class EntityB
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;
    @OneToMany(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "FK_journeyId")
    @Fetch(FetchMode.JOIN)
    private List<EntityC> cEntities = new ArrayList<>();


public interface ReservationRepository extends JpaRepository<EntityA, Integer>

    public List<EntityA> findByUserIdAndStatus(String userId);

【问题讨论】:

【参考方案1】:

FetchType 定义了集合的加载方式。是立即加载还是延迟加载(按需)。

相比之下,FetchMode 定义了加载集合的机制。当您将收藏标记为:

@OneToMany(cascade = CascadeType.PERSIST)
@Fetch(FetchMode.JOIN)

这是一个废话,因为默认情况下 OneToMany 的 fetchType 是惰性的,但你不能在惰性集合上使用 JOIN 机制。为了获得 JOIN,您需要将其设置为 EAGER。

hibernate 中默认的 FetchMode 是 SELECT,这是首选的 fetchmode,因为它对于基于键的访问的缓存使用非常有效。我建议您使用 FetchType.LazyFetchMode.SELECT启用集合批处理

【讨论】:

我已经使用了 Fetchtype Eager 和 FetchMode 连接,但它不起作用。我需要这种组合,因为表有大量数据,我需要立即获取所有记录。无论我做什么,这种组合都不适用于数据 JPA 查询方法。我什至用命名查询注释了我的 JPARepository 方法,显式地编写了一个 SQL 连接查询。即使这样也行不通。 @Navdeep 你不能在第三级加入加入加入。启用查询批处理,最终得到“select from C where id in ......”这里不是你需要的Join,而是“@Batch”注解 好的,谢谢。我会试试的。只是想知道:如果我的存储库中有一个 findById 方法,那么它就可以工作。只触发一个查询。当我有 findByAnyOtherColumn 时,就会出现问题。

以上是关于spring data JPA忽略查询方法上的fetchmode的主要内容,如果未能解决你的问题,请参考以下文章

Spring Data JPA - 使用 REST 调用上的查询参数从方法名称生成查询

Spring Data JPA 忽略空参数

jsonb字段上的Spring-Data-JPA本机查询

Spring Data JPA 原生查询结果实体

spring-data-jpa中的查询方法

学习Spring-Data-Jpa---定义方法查询