【问题标题】:Spring data jpa left join fetch and where clauseSpring data jpa left join fetch 和 where 子句
【发布时间】:2017-01-18 14:33:38
【问题描述】:

我的存储库中有以下查询:

SELECT p FROM Project p JOIN p.users u WHERE u.login =:login

用户和项目之间存在多对多关系。 一切正常,它返回用户的项目,但我希望它为每个项目返回相应的用户集。

更新:按照 mateuszlo 的建议尝试了以下操作:

SELECT p FROM Project p JOIN FECTH p.users JOIN p.users u WHERE u.login =:login

但现在我遇到了以下异常:

nested exception is java.lang.IllegalArgumentException: Count query validation failed for method public abstract org.springframework.data.domain.Page com.example.app.repository.ProjectRepository.findAllByUserLo‌​gin(java.lang.String‌​,org.springframework‌​.data.domain.Pageabl‌​e)! org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list

【问题讨论】:

标签: java spring jpa spring-data-jpa


【解决方案1】:

不可能为 FETCH JOIN 查询创建命名别名以在 WHERE 语句中使用它。 JPA 故意不允许这样做,因为它很容易导致不需要的情况。

考虑一个Project X,它有 3 个Users:John、Tom 和 Mike。使用 FETCH JOIN 查询具有用户 John 的项目将返回 Project X,其中只有一个 User - John。这将产生一个不完整的Project 实体,与当前数据库状态不一致。

所以你要做的就是加入两次。第一次使用正常的JOIN,识别正确的Projet记录,然后第二次使用FETCH JOIN获取对应的Users

SELECT p FROM Project p 
JOIN FETCH p.users
JOIN p.users u WHERE u.login =:login

【讨论】:

  • 谢谢 mateuszlo。已经尝试过,但出现以下异常:嵌套异常是 java.lang.IllegalArgumentException: Count query validation failed for method public abstract org.springframework.data.domain.Page com.example.app.repository.ProjectRepository.findAllByUserLogin(java.lang .String,org.springframework.data.domain.Pageable)! org.hibernate.QueryException:查询指定连接提取,但提取关联的所有者不在选择列表中
【解决方案2】:

首先我假设您正在使用分页?那是您的 JPA 查询方法上有一个 Pagable 参数吗?如果是这样,有两种方法可以解决这个问题。

计数查询

@Query(value = "SELECT p FROM Project p " +
       "LEFT JOIN FETCH p.users u WHERE u.login = :login",
countQuery = "SELECT COUNT(u) FROM User u WHERE u.login = :login")
Page<Project> fetchProjectsByUserLogin(String login, Pageable pageable);

实体图

@Query(value = "SELECT p FROM Project p " +
       "LEFT JOIN p.users u WHERE u.login = :login")
@EntityGraph(attributePaths = {"users"}, type = EntityGraph.EntityGraphType.FETCH)
Page<Project> fetchProjectsByUserLogin(String login, Pageable pageable);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-21
    • 2015-01-30
    • 2014-05-25
    • 2021-09-11
    • 2021-09-29
    相关资源
    最近更新 更多