I am working on a project with post, label and subsection. A post has Many-to-one relation with a label and a subsection. And a post can have no label, that mean label is null. I want to find post that
is not disabled
label is not disabled or if label is null, include it
subsection is not disabled
equals to a subsection or if subsection is null return all with all subsection
match title or content
@Query("SELECT p FROM Post p " +
"WHERE p.isDisabled = FALSE " +
"AND (p.label IS NULL OR p.label.isDisabled = FALSE) " +
"AND p.subsection.isDisabled = FALSE " +
"AND (p.subsection = :subsection OR :subsection IS NULL) " +
"AND (LOWER(p.title) LIKE LOWER(CONCAT('%', :query, '%')) OR LOWER(p.content) LIKE LOWER(CONCAT('%', :query, '%'))) ")
Page<Post> findViewablePostsWN(
Subsection subsection,
String query,
Pageable pageable
);
But the data return is empty.
Everytime I use this "AND (p.label IS NULL OR p.label.isDisabled = FALSE) " then it will not return anything. Although there is no label disabled in the database as well as there are posts with null label.
If I only use "AND (p.label = NULL) " , posts with null label is returned. So I try to filter with list in Java and it give me right data.
I don't understand why this is not working.
I ended up using left join with p.label and it is working well.
@Query("SELECT p FROM Post p " +
"LEFT JOIN p.label l " +
"WHERE p.isDisabled = FALSE " +
"AND (l = NULL OR l.isDisabled = FALSE) " +
"AND p.subsection.isDisabled = FALSE " +
"AND (p.subsection = :subsection OR :subsection IS NULL) " +
"AND (LOWER(p.title) LIKE LOWER(CONCAT('%', :query, '%')) OR LOWER(p.content) LIKE LOWER(CONCAT('%', :query, '%'))) ")
Page<Post> findViewablePosts(
Subsection subsection,
String query,
Pageable pageable
);
I donot know why Spring JPA cannot perform good check on NULL column and NOT NULL like that.