You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过@Query注解获取包含所有关联学校的指定城市?

获取包含关联学校的指定城市的几种方法

嘿,这个问题我之前也碰到过!因为JPA默认对@OneToMany关联用的是懒加载(FetchType.LAZY),直接查City的话,schools集合是个代理对象,在Controller里访问很容易触发懒加载异常。下面给你两种靠谱的解决方案,都可以用在你的CityRepository里,然后在Controller里调用就行:

方法一:用@Query写Fetch Join的JPQL

这种方式最直接,通过JPQL的JOIN FETCH一次性把City和它的schools都查出来,避免N+1查询问题:

@Repository
public interface CityRepository extends JpaRepository<City, Long>{
    @Query("SELECT c FROM City c JOIN FETCH c.schools WHERE c.id = :cityId")
    Optional<City> findByIdWithSchools(@Param("cityId") Long cityId);
}

然后在你的CityController里调用这个方法:

@GetMapping("/{id}")
public ResponseEntity<City> getCityWithSchools(@PathVariable Long id) {
    return cityRepository.findByIdWithSchools(id)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.notFound().build());
}

方法二:用@EntityGraph简化代码

如果你不想写JPQL,Spring Data JPA的@EntityGraph注解可以帮你更简洁地实现同样的效果,它会告诉JPA在查询City时同时抓取关联的schools属性:

@Repository
public interface CityRepository extends JpaRepository<City, Long>{
    @EntityGraph(attributePaths = {"schools"})
    Optional<City> findById(Long cityId);
}

这种情况下Controller里直接调用默认的findById方法就行,因为注解已经帮我们处理了关联抓取:

@GetMapping("/{id}")
public ResponseEntity<City> getCityWithSchools(@PathVariable Long id) {
    return cityRepository.findById(id)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.notFound().build());
}

小提醒

  • 两种方法本质都是解决懒加载的问题,一次性加载关联数据,避免在事务外访问懒加载集合导致的异常。
  • 如果是查询多个City并关联schools,用Fetch Join要注意分页的问题(可能需要额外处理),但你这里是查单个城市,完全没问题。

内容的提问来源于stack exchange,提问作者James Hao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:38:46