Spring Data DTO projection

10,267

From Spring Data JPA - Reference Documentation:

Another way of defining projections is using value type DTOs that hold properties for the fields that are supposed to be retrieved. These DTO types can be used exactly the same way projection interfaces are used, except that no proxying is going on here and no nested projections can be applied.

I think the reason is this...

Share:
10,267
pegasus
Author by

pegasus

JavaScript geek

Updated on June 15, 2022

Comments

  • pegasus
    pegasus almost 2 years

    We would like to use a DTO projection over the interface one, thus we created following DTO objects:

    PersonDto

    @Data
    @Builder
    @AllArgsConstructor
    public class PersonDto {
    
        private String name;
    
        private String email;
    
        private AddressDto address;
    
    }
    

    AddressDto

    @Data
    @Builder
    @AllArgsConstructor
    public class AddressDto {
    
        private String address;
    
        private String streetNumber;
    
    }
    

    A repository

    @Repository
    public interface PersonRepository extends JpaRepository<PersonEntity, Long> {
    
        List<PersonDto> findAllDtoedBy();
    
    }
    

    However, when called we get the exception:

    Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Unable to locate appropriate constructor on class [com.example.projections.model.PersonDto]. Expected arguments are: java.lang.String, java.lang.String, com.example.projections.model.AddressEntity [select new com.example.projections.model.PersonDto(generatedAlias0.name, generatedAlias0.email, address) from com.example.projections.model.PersonEntity as generatedAlias0 left join generatedAlias0.address as address]
        at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74) ~[hibernate-core-5.2.11.Final.jar:5.2.11.Final]
        at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:91) ~[hibernate-core-5.2.11.Final.jar:5.2.11.Final]
        at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:272) ~[hibernate-core-5.2.11.Final.jar:5.2.11.Final]
        at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:189) ~[hibernate-core-5.2.11.Final.jar:5.2.11.Final]
    

    Note the line: "...Expected arguments are: java.lang.String, java.lang.String, com.example.projections.model.AddressEntity...".

    Obviously it expects the model object AddressEntity, and gets confused when a DTO object (AddressDto) is found instead.

    So the question is, since this works with the interface projection, we would expect this to be supported by a DTO projection as well? By looking at the samples on GitHub (https://github.com/spring-projects/spring-data-examples/blob/master/jpa/example/src/main/java/example/springdata/jpa/projections/CustomerRepository.java) and in the Spring Data JPA documentation, we didn't see an example for this case, but we also din't see an explicit statement that this isn't supported