【问题标题】:JPA: Join Fetch results to NULL on empty many sideJPA:在空的多方面将 Fetch 结果加入 NULL
【发布时间】: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 用户。

【问题讨论】:

  • 使用“左连接”

标签: java hibernate jpa spring-data lazy-loading


【解决方案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 专门针对这种情况
猜你喜欢
  • 2020-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-17
  • 2019-06-27
  • 1970-01-01
  • 1970-01-01
  • 2017-10-04
相关资源
最近更新 更多