FetchMode如何在Spring Data JPA中工作

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


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


(“ sql”)


SELECT * FROM place p where id = arg

SELECT * FROM user u where u.id = place.user.id

SELECT * 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 = arg

SELECT * 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

}

仓库:


PlaceRepository


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

}


冉冉说
浏览 631回答 3
3回答

动漫人物

我认为Spring Data会忽略FetchMode。在使用Spring Data时,我总是使用@NamedEntityGraph和@EntityGraph批注@Entity@NamedEntityGraph(name = "GroupInfo.detail",&nbsp; attributeNodes = @NamedAttributeNode("members"))public class GroupInfo {&nbsp; // default fetch mode is lazy.&nbsp; @ManyToMany&nbsp; List<GroupMember> members = new ArrayList<GroupMember>();&nbsp; …}@Repositorypublic interface GroupRepository extends CrudRepository<GroupInfo, String> {&nbsp; @EntityGraph(value = "GroupInfo.detail", type = EntityGraphType.LOAD)&nbsp; GroupInfo getByGroupName(String name);}

不负相思意

首先,@Fetch(FetchMode.JOIN)并且@ManyToOne(fetch = FetchType.LAZY)是对立的,一个指示EAGER的获取,而另一个则指示LAZY的获取。急切的获取很少是一个好的选择,对于可预期的行为,最好使用query-time JOIN FETCH指令:public interface PlaceRepository extends JpaRepository<Place, Long>, PlaceRepositoryCustom {&nbsp; &nbsp; @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")&nbsp; &nbsp; Place findById(@Param("id") int id);}public interface CityRepository extends JpaRepository<City, Long>, CityRepositoryCustom {&nbsp;&nbsp; &nbsp; @Query(value = "SELECT c FROM City c LEFT JOIN FETCH c.state where c.id = :id")&nbsp; &nbsp;&nbsp; &nbsp; City findById(@Param("id") int id);}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java