2017-09-24 1 views
2

Nous aimerions utiliser une projection DTO sur l'interface un, donc nous avons créé des objets DTO suivants:ressort données projection DTO

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; 

} 

Un dépôt

@Repository 
public interface PersonRepository extends JpaRepository<PersonEntity, Long> { 

    List<PersonDto> findAllDtoedBy(); 

} 

Toutefois, lorsqu'il est appelé, nous obtenons l'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] 

Notez la ligne: » ... arguments attendus sont: java.lang.String, java.lang.String, com.example.projections.model. AddressEntity ... ".

Évidemment, il attend l'objet modèle AddressEntity et se confond lorsqu'un objet DTO (de AddressDto) se trouve à la place.

La question est donc, plus que cela fonctionne Avec la projection de l'interface, on s'attendrait à ce que cela soit supporté par une projection DTO? En regardant les exemples sur GitHub (https://github.com/spring-projects/spring-data-examples/blob/master/jpa/example/src/main/java/example/springdata/jpa/projections/CustomerRepository.java) et dans la documentation Spring Data JPA, nous n'avons pas vu d'exemple pour ce cas, mais nous ne voyons pas non plus une déclaration explicite que ce n'est pas pris en charge

Répondre

1

De Spring Data JPA - Reference Documentation:

Une autre façon de définir des projections utilise DTO de type valeur qui détiennent des propriétés pour les champs qui sont censés être récupérés. Ces types de DTO peuvent être utilisés exactement de la même manière que les interfaces de projection, sauf qu'il n'y a pas de proxy ici et que aucune projection imbriquée ne peut être appliquée.

Je pense que la raison est ...

+0

Huh, nous avons manqué en quelque sorte cette partie. – pegasus

0

Vous utilisez @AllArgsConstructor annotation.

@AllArgsConstructor génère un constructeur avec 1 paramètre pour chaque champ de votre classe.

Il n'y a donc pas de constructeur sans-argument présent.

Vous pouvez mettre à jour votre méthode de prise en pension:

List<PersonDto> findAllDtoedBy(); 

pour contenir certains paramètres ou fournir un constructeur sans arg dans vos classes. (Probablement en utilisant @NoArgsConstructor)