为了账号安全,请及时绑定邮箱和手机立即绑定

FetchMode如何在Spring Data JPA中工作

FetchMode如何在Spring Data JPA中工作

冉冉说 2019-11-08 14:28:33
我确实在项目中的三个模型对象之间有关系(文章末尾的模型和存储库片段)。当我调用PlaceRepository.findById它时,会触发三个选择查询:(“ sql”)SELECT * FROM place p where id = argSELECT * FROM user u where u.id = place.user.idSELECT * FROM city c LEFT OUTER JOIN state s on c.woj_id = s.id where c.id = place.city.id(对我而言)这是非常不正常的行为。据阅读Hibernate文档后所知,它应该始终使用JOIN查询。在类中FetchType.LAZY更改为 查询时(带有附加SELECT 的查询)没有任何区别,而在类更改为 (使用JOIN查询时)则没有变化。FetchType.EAGERPlaceCityFetchType.LAZYFetchType.EAGER当我使用CityRepository.findById抑制射击时,有两个选择:SELECT * FROM city c where id = argSELECT * FROM state s where id = city.state.id我的目标是在所有情况下都具有sam行为(始终为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}仓库:PlaceRepositorypublic interface PlaceRepository extends JpaRepository<Place, Long>, PlaceRepositoryCustom {    Place findById(int id);}UserRepository: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);}
查看完整描述

3 回答

?
动漫人物

TA贡献1815条经验 获得超10个赞

我认为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);


}


查看完整回答
反对 回复 2019-11-08
?
不负相思意

TA贡献1777条经验 获得超10个赞

首先,@Fetch(FetchMode.JOIN)并且@ManyToOne(fetch = FetchType.LAZY)是对立的,一个指示EAGER的获取,而另一个则指示LAZY的获取。


急切的获取很少是一个好的选择,对于可预期的行为,最好使用query-time JOIN FETCH指令:


public interface PlaceRepository extends JpaRepository<Place, Long>, PlaceRepositoryCustom {


    @Query(value = "SELECT p FROM Place p LEFT JOIN FETCH p.author LEFT JOIN FETCH p.city c LEFT JOIN FETCH c.state where p.id = :id")

    Place findById(@Param("id") int id);

}


public interface CityRepository extends JpaRepository<City, Long>, CityRepositoryCustom { 

    @Query(value = "SELECT c FROM City c LEFT JOIN FETCH c.state where c.id = :id")   

    City findById(@Param("id") int id);

}


查看完整回答
反对 回复 2019-11-08
  • 3 回答
  • 0 关注
  • 630 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信