FetchMode 在 Spring Data JPA 中是如何工作的 [英] How does the FetchMode work in Spring Data JPA

查看:28
本文介绍了FetchMode 在 Spring Data JPA 中是如何工作的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的项目中的三个模型对象之间确实存在关系(文章末尾的模型和存储库片段.

I do have a relation between three model object in my project (model and repository snippets in the end of the post.

当我调用 PlaceRepository.findById 时,它会触发三个选择查询:

When I call PlaceRepository.findById it does fire three select queries:

("sql")

  1. SELECT * FROM place p where id = arg
  2. SELECT * FROM user u where u.id = place.user.id
  3. SELECT * FROM city c LEFT OUTER JOIN state s on c.woj_id = s.id where c.id = place.city.id

那是相当不寻常的行为(对我来说).据我所知,在阅读 Hibernate 文档后,它应该始终使用 JOIN 查询.在Place类中将FetchType.LAZY改为FetchType.EAGER时查询没有区别(查询附加SELECT),相同对于 City 类,当 FetchType.LAZY 更改为 FetchType.EAGER(使用 JOIN 查询).

That's rather unusual behavior (for me). As far as I can tell after reading Hibernate documentation it should always use JOIN queries. There is no difference in the queries when FetchType.LAZY changed to FetchType.EAGER in the Place class (query with additional SELECT), the same for the City class when FetchType.LAZY changed to FetchType.EAGER (query with JOIN).

当我使用 CityRepository.findById 抑制触发两个选择:

When I use CityRepository.findById suppressing fires two selects:

  1. SELECT * FROM city c where id = arg
  2. SELECT * FROM state s where id = city.state.id

我的目标是在所有情况下都具有相同的行为(总是加入或选择,但首选加入).

My goal is to have a the sam behavior in all situations (either always JOIN or SELECT, JOIN preferred though).

模型定义:

地点:

@Entity
@Table(name = "place")
public class Place extends Identified {

    @Fetch(FetchMode.JOIN)
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_user_author")
    private User author;

    @Fetch(FetchMode.JOIN)
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "area_city_id")
    private City city;
    //getters and setters
}

城市:

@Entity
@Table(name = "area_city")
public class City extends Identified {

    @Fetch(FetchMode.JOIN)
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "area_woj_id")
    private State state;
    //getters and setters
}

存储库:

位置存储库

public interface PlaceRepository extends JpaRepository<Place, Long>, PlaceRepositoryCustom {
    Place findById(int id);
}

用户存储库:

public interface UserRepository extends JpaRepository<User, Long> {
        List<User> findAll();
    User findById(int id);
}

城市存储库:

public interface CityRepository extends JpaRepository<City, Long>, CityRepositoryCustom {    
    City findById(int id);
}

推荐答案

我认为 Spring Data 忽略了 FetchMode.使用 Spring Data 时,我总是使用 @NamedEntityGraph@EntityGraph 注释

I think that Spring Data ignores the FetchMode. I always use the @NamedEntityGraph and @EntityGraph annotations when working with Spring Data

@Entity
@NamedEntityGraph(name = "GroupInfo.detail",
  attributeNodes = @NamedAttributeNode("members"))
public class GroupInfo {

  // default fetch mode is lazy.
  @ManyToMany
  List<GroupMember> members = new ArrayList<GroupMember>();

  …
}

@Repository
public interface GroupRepository extends CrudRepository<GroupInfo, String> {

  @EntityGraph(value = "GroupInfo.detail", type = EntityGraphType.LOAD)
  GroupInfo getByGroupName(String name);

}

此处查看文档

这篇关于FetchMode 在 Spring Data JPA 中是如何工作的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆