Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPQL query - hibernate: with-clause not allowed on fetched associations

I have JPA Repository and JPQL query like this:

@Query("SELECT c from Campaign c" +
        " left join fetch c.postsList p on p.status = :postStatus" +
        " left join fetch p.platform" +
        " left join fetch c.campaignStatistics stat on stat.updateDate = :updateDate" +
        " where c.id =:id")
Campaign findCampaignWithPosts(
        @Param("id") Long id,
        @Param("postStatus") PostStatus postStatus,
        @Param("updateDate") LocalDate updateDate);

But it doesn' work. I get:

org.hibernate.hql.internal.ast.QuerySyntaxException: with-clause not allowed on fetched associations; use filters

I went to study information about the JPA 2.1 specification and that's what I found:

The join condition used for a join comes from the mapping's join columns. This means that the JPQL user is normally free from having to know how every relationship is joined. In some cases it is desirable to append additional conditions to the join condition, normally in the case of outer joins. This can be done through the ON clause. The ON clause is defined in the JPA 2.1 specifiation, and may be supported by some JPA providers. EclipseLink : Hibernate : TopLink - support the ON clause.

It should be noted that this type of query does not help me at all, becouse in this query sometimes i get null, where clause use after join tables.

   @Query("SELECT c from Campaign c" +
            " left join fetch c.postsList p" +
            " left join fetch p.platform" +
            " left join fetch c.campaignStatistics stat" +
            " where c.id =:id" +
            " and p.status = :postStatus" +
            " and stat.updateDate = :updateDate")

What to do in this case? Is there no alternative solution other than how to use the native query? But then the meaning of almost all JPQL queries is lost. I use hibernate version 5.2.12

like image 362
Peter Kozlovsky Avatar asked Nov 29 '17 01:11

Peter Kozlovsky


People also ask

What is JPQL query in hibernate?

The Hibernate Query Language (HQL) and Java Persistence Query Language (JPQL) are both object model focused query languages similar in nature to SQL. JPQL is a heavily-inspired-by subset of HQL. A JPQL query is always a valid HQL query, the reverse is not true however.

Which of the following clauses are supported in JPQL?

JPQL can retrieve information or data using SELECT clause, can do bulk updates using UPDATE clause and DELETE clause.

Can we use subquery in JPQL?

Yes, It is possible to use subquery with IN operator in JPQL. I had a similar usecase and it worked for me. My query was as follows.

Is JPQL HQL database independent?

HQL is database independent and translated into SQL by Hibernate at runtime. When you write HQL, you can concentrate on the objects and properties without knowing much detail about the underlying database.


1 Answers

You are right, when you add and p.status = :postStatus it filters out the results where the right side of the join does not exist (i.e. when the Campaign has no posts).

What worked for me is to add an OR clause to accept the case where the right side of the join is NULL.

So, you should replace and p.status = :postStatus with and (p IS NULL OR p.status = :postStatus).

So this request should work :

@Query("SELECT c from Campaign c" +
            " left join fetch c.postsList p" +
            " left join fetch p.platform" +
            " left join fetch c.campaignStatistics stat" +
            " where c.id =:id" +
            " and (p is NULL OR p.status = :postStatus)" +
            " and stat.updateDate = :updateDate")

As for the error message you received, I think you should not add the ON clause because that is already handled by JPA/Hibernate.

I am using Hibernate 5.0.12.

like image 89
HL'REB Avatar answered Sep 20 '22 07:09

HL'REB