To collect only the data i need i use following query for object Declaration:
@Query(value = "select d.id as id "
+ " , d.statusChanged as statusChanged "
+ " from Declaration d ",
countQuery="select count(id) from Declaration")
Page<DeclarationIDTO> findAllDeclarationListIDTO(Pageable pageable);
DeclarationIDTO has a getId() and a getStatusChanged().
This works.
Now i want to add the id of the freelancer like this:
@Query(value = "select d.id as id "
+ " , d.statusChanged as statusChanged "
+ " , f.id as 'freelancer.id' "
+ " from Declaration d join d.freelancer f",
countQuery="select count(id) from Declaration")
Page<DeclarationIDTO> findAllDeclarationListIDTO(Pageable pageable);
The DeclarationIDTO has a getFreelancer() which has a getId() but i get an error:
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: expecting IDENT, found ''freelancer.id'' near line 1, column 66 [select d.id as id , d.statusChanged as statusChanged , f.id as 'freelancer.id' from nl.tibi.sbys.domain.Declaration d join d.freelancer f]
Any idea how to work with object chain?
Possible work arounds:
1) flatten interface:
@Query(value = "select d.id as id "
+ " , d.statusChanged as statusChanged "
+ " , f.id as 'freelancer_id' "
+ " from Declaration d join d.freelancer f",
countQuery="select count(id) from Declaration")
Page<DeclarationIDTO> findAllDeclarationListIDTO(Pageable pageable);
DeclarationIDTO will have getId(), getStatusChanged() and getFreelancer_id()
Downside is the interface will have to copy all needed freelancer fields and i have to use a mapper to map the freelancer_id to a DTO object with a freelancer.id
2) work with constructor instead of interface:
@Query(value = "select new DeclarationDTO(d.id "
+ " , d.statusChanged "
+ " , f.id) "
+ " from Declaration d join d.freelancer f",
countQuery="select count(id) from Declaration")
Page<DeclarationDTO> findAllDeclarationListIDTO(Pageable pageable);
Downside is i will need many constructors for different pages or need to select null values cluttering my query
3) Multiple queries per object, this is a performance hit and a lot of work.
4) Select full sub objects:
@Query(value = "select d.id as id "
+ " , d.statusChanged as statusChanged "
+ " , f as freelancer "
+ " from Declaration d join d.freelancer f",
countQuery="select count(id) from Declaration")
Page findAllDeclarationListIDTO(Pageable pageable);
DeclarationIDTO has a getId() getStatusChanged() and getFreelancer()
This works there are still to many data collected which is a downside on performance.
If there is a simple solution for getting f.id it would solve all downsides.
There seems an answer here:
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections
When time i will look into it.