javaspring-data-jpanativequery

Spring Data JPA NULL condition in Native Query not working


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

  1. is not disabled

  2. label is not disabled or if label is null, include it

  3. subsection is not disabled

  4. equals to a subsection or if subsection is null return all with all subsection

  5. 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.


Solution

  • 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.