简体   繁体   中英

Spring data jpa left join fetch and where clause

I have the following query in my repository:

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

There is a Many To Many relationshio between user and project. Everything works fine and it returns the user's projects, but I want it for each project to return the corresponding set of users.

UPDATE: Tried the following as mateuszlo suggested:

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

But now i got the following exception:

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

It is impossible to create a named alias for a FETCH JOIN query to use it in a WHERE statement. JPA doesn't allow this on purpose, because it could easly lead to unwanted situations.

Consider a Project X, which has 3 Users : John, Tom and Mike. Query with FETCH JOIN for projects, that have user John would return Project X with only one User - John. That would produce an incomplete Project entity, which is inconsistent with current database state.

So what you have to do is to join twice. First time with normal JOIN , to identify proper Projet records, and then second time with FETCH JOIN to fetch correspoding Users :

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

First off I'm assuming you're using pagination? That is you have a Pagable parameter on your JPA query method? If so, there are two ways to solve this.

Count query

@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);

Entity Graph

@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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM