JPA:在空的多方面将 Fetch 结果加入 NULL
Posted
技术标签:
【中文标题】JPA:在空的多方面将 Fetch 结果加入 NULL【英文标题】:JPA: Join Fetch results to NULL on empty many side 【发布时间】:2017-10-08 08:02:05 【问题描述】:我在 User 和 GameMap 之间有一对多的关系。一个用户可以拥有多张地图。
用户类别:
// LAZY LOADED
@OneToMany(cascade = CascadeType.ALL, mappedBy = "creater")
private final List<GameMap> maps = new ArrayList<>();
但是,有时我需要预先加载地图。为了避免在关闭 Session 后出现 LazyInitializationException,我有两种检索用户的变体。
用户存储库:
public interface UserRepository extends JpaRepository<User, Long>
Optional<User> findById( Long id );
@Query("SELECT u FROM User u JOIN FETCH u.maps WHERE u.id = (:id)")
public User findByIdEagerFetch( @Param("id") Long id );
问题: 但是,JPQL JOIN FETCH 变体可以一次性立即加载用户,并且他的地图返回 NULL 用户如果表中没有此用户的地图。
问题: 我如何重写 JPQL 语句以检索用户和可选(!)他的所有地图,但如果没有地图,那没关系,但不要返回 NULL 用户。
【问题讨论】:
使用“左连接” 【参考方案1】:FETCH JOIN
实际上会解析为 SQL 中的 inner 连接。这意味着User
表中没有映射的任何记录/实体都将从结果集中删除。您需要 FETCH JOIN
上的 LEFT
关键字才能获得所有结果,即使是那些没有地图的结果。
@Query("SELECT u FROM User u LEFT JOIN FETCH u.maps WHERE u.id = (:id)")
public User findByIdEagerFetch( @Param("id") Long id );
【讨论】:
就我而言,它没有按我的预期工作。我有一对多的关系,有完全相同的问题。我使用相同的 JPQL,如果“许多”端没有相关实体,则请求的实体列表(如上面示例中的“用户”)将被正确返回。但是,如果请求的实体引用了多个相关实体(例如,示例中的用户有 2 个地图),它会重复多次,每个相关实体一次。在 SQL 结果行和 java 对象中。我把'distinct'查询并解决了问题,但我想知道我是否正确执行,以后不会出现问题。 @tequilacat distinct 专门针对这种情况以上是关于JPA:在空的多方面将 Fetch 结果加入 NULL的主要内容,如果未能解决你的问题,请参考以下文章