2

I map the result of the following JPQL-Query directly to a SpecialCustomDto object instead of the used javax.persistency entity object MyEntity. But I do not know, how to access the COUNT(DISTINCT e.attributeB), which will be mapped to the SpecialCustomDto.

This is the query.

@Repository
public interface MyEntityRepository extends JpaRepository<MyEntity, Long> {

  @Query("SELECT new com.test.SpecialCustomDto(e.attributeA, COUNT(DISTINCT e.attributeB)) as specialCustomDto "
         + "FROM MyEntity e WHERE 5 = specialCustomDto.count GROUP BY e.attributeA")
  List<SpecialCustomDto> getSpecialCustomDtos(); 
}

As soon as I start the spring-boot application, Hibernate throws me following error:

Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: as near line 1, column...

I don't know how to access the aggregated COUNT(DISTINCT e.attributeB) element of the newly created SpecialCustomDto. Without the additional WHERE-clause, the mapping works as expected.

2
  • Check if it is allowed with new com.test.SpecialCustomDto(e.attributeA, COUNT e.attributeB) Commented Mar 5, 2019 at 15:00
  • Thanks for the advice, I tried it and this was the result: Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: COUNT near line 1, Commented Mar 5, 2019 at 15:02

2 Answers 2

3

Aggregate functions can be used as condition using HAVING. The same as in native SQL.

SELECT new com.test.SpecialCustomDto(e.attributeA, COUNT(e.attributeB))
FROM MyEntity e 
GROUP BY e.attributeA
HAVING COUNT(e.attributeB) = 5  
Sign up to request clarification or add additional context in comments.

Comments

2

Remove the alias, move the condition to a HAVING-clause since it operates on an aggregate-value and just put the count-expression in there.

public interface MyEntityRepository extends JpaRepository<MyEntity, Long> {

  @Query("SELECT new com.test.SpecialCustomDto(e.attributeA, COUNT(DISTINCT e.attributeB)) "
         + "FROM MyEntity e "
         + "GROUP BY e.attributeA "
         + "HAVING COUNT(DISTINCT e.attributeB) = 5")
  List<SpecialCustomDto> getSpecialCustomDtos(); 
}

Note: The @Repository is superfluous.

2 Comments

Thanks for your answer! It worked as suggested. But in general: is it somehow possible to create an "AS" alias for the response mapping?
I don't think so.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.