简体   繁体   中英

Why JPA query left join on codition not working?

I'm using Hibernate as JPA implementation and have two tables: User and Agency .

Each Agency can have many users. A User can have one or zero Agency

User

public class User {
  @Id
  private String userId;

  @ManyToOne
  @JoinColumn(nullable=true)
  @NotFound(action=NotFoundAction.IGNORE)
  private Agency agency;
}

Agency

public class Agency {
  @Id
  private String agencyCd;

  private String delFlg; //0 means in use

  @OneToMany(mappedBy="agency")       
  private List<User> userList;
}

In the repository, query is

@Query("SELECT DISTINCT u FROM User u LEFT JOIN u.agency a on a.delFlg='0')

My problem is, left join on codition(a.delFlg='0') is not working.

Agencies with delFlg is 1 are all included in the results.

How can I find user with left joined agencies whose delFlg is 0?

It seems your case is explicitly described in the JPA Specification 4.2 Section 4.4.5.2

An outer join without a specified join condition has an implicit join condition over the foreign key relationship corresponding to the join_association_path_expression . It would typically be mapped to a SQL outer join with an ON condition on the foreign key relationship as in the queries below: Java Persistence query language:

 SELECT s.name, COUNT(p) FROM Suppliers s LEFT JOIN s.products p GROUP BY s.name

SQL:

 SELECT s.name, COUNT(p.id) FROM Suppliers s LEFT JOIN Products p ON s.id = p.supplierId GROUP By s.name

An outer join with an explicit ON condition would cause an additional specified join condition to be added to the generated SQL: Java Persistence query language:

 SELECT s.name, COUNT(p) FROM Suppliers s LEFT JOIN s.products p ON p.status = 'inStock' GROUP BY s.name

SQL:

 SELECT s.name, COUNT(p.id) FROM Suppliers s LEFT JOIN Products p ON s.id = p.supplierId AND p.status = 'inStock' GROUP BY s.name

Note that the result of this query will be different from that of the following query: SELECT s.name, COUNT(p) FROM Suppliers s LEFT JOIN s.products p WHERE p.status = 'inStock' GROUP BY s.name The result of the latter query will exclude suppliers who have no products in stock whereas the former query will include them.

So your query should probably be:

SELECT u 
FROM User u 
LEFT JOIN u.agency a 
WHERE a IS NULL 
OR a.delFlg='0'

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