java - Spring Data JPA 中的 FetchMode 是如何工作的

标签 java spring hibernate jpa spring-data-jpa

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

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

("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),同理当 FetchType.LAZY 更改为 FetchType.EAGER(使用 JOIN 查询)时的 City 类。

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

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

我的目标是在所有情况下都具有相同的行为(始终 JOIN 或 SELECT,但首选 JOIN)。

模型定义:

地点:

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

存储库:

PlaceRepository

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 注释

@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);

}

查看文档 here

关于java - Spring Data JPA 中的 FetchMode 是如何工作的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29602386/

相关文章:

java - 如何修改 JTabbedPane 选项卡上的 JLabel?

spring - 方法不允许 405,在 grails 从 2.5.2 升级到 3.3.11 后点击 POST 请求时

java - 为什么 hbm2ddl.auto 'update' 属性不起作用或者它是如何工作的?

java - 是否有可能在 O(1) 中得到 m 个字符长度组合的第 k 个元素?

java - 我的远程服务器 (Amazon EC2) 是否需要运行 2 个不同的服务器才能运行 EmberJS 和 Spring Boot?

java - 使用 RequestParam 上传文件

java - 用子类替换 Spring Bean 时出错

spring - Hibernate - 未能延迟初始化角色集合 - 无法初始化代理 - 无 session

java - 如何使用 hibernate 配置 Jaybird

java - 将 Java Spring Rest Controller 中发布的 JSON 映射到 POJO