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的主要内容,如果未能解决你的问题,请参考以下文章

在空的剑道网格上排序显示旧数据

带类的matlab - 将结构保存在空的双数组中

如何将网格线保留在空的 TableView Javafx 中

为啥在空的 try 块中使用 try finally ?

JPA 急切未加入

我可以在空的arraylist索引上替换或放置一个新字符串吗