2017-09-14 1 views
2

Je voudrais utiliser la technique Spring Data Projection pour extraire d'une table seulement certains champs (et pas tous les champs de la table).Désactiver la création de requête à partir du nom de la méthode - utilisation de projections (Spring Data JPA)

Comme décrit dans la documentation (https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections) Je créé une interface simple, par exemple:

interface NamesOnly { 
    String getFirstname(); 
    String getLastname(); 
} 

mais j'ai quelques problèmes à l'utiliser.

Problème 1:

Tout d'abord, je voudrais utiliser le nom findAll() pour créer une requête qui trouve toutes les lignes avec seulement deux champs (firstName et lastName):

@Repository 
public interface PersonaRepository extends JpaRepository<Persona, Long> { 
    List<NamesOnly> findAll(); 
} 

mais dans ce cas, j'ai ces erreurs (peut-être parce que findAll() est une méthode de JpaRepository):

- implements org.springframework.data.jpa.repository.JpaRepository<it.andrea.test.domain.Persona,java.lang.Long>.findAll 
- The return type is incompatible with JpaRepository<Persona,Long>.findAll() 

Problème 2:

Ok, alors j'essaie de changer le nom de la méthode à findAllOnlyNames():

@Repository 
public interface PersonaRepository extends JpaRepository<Persona, Long> { 
    List<NamesOnly> findAllOnlyNames(); 
} 

Mais maintenant, j'ai cette erreur:

Caused by: org.springframework.data.mapping.PropertyReferenceException: No property findAllOnlyNames found for type Persona! 

Parce que Spring essayer pour créer une requête à partir du nom.

1) Il est possible de réutiliser le nom de la méthode findAll() sans avoir de problèmes avec JpaRepository?

2) Il pourrait être possible de désactiver la création de la requête à partir du nom de la méthode (uniquement pour certaines requêtes, pas pour tous les projets ou référentiels)?

Merci beaucoup.

Cordialement, Andrea

Répondre

2

Vous pouvez spécifier une requête explicite plutôt que de compter sur elle étant dérivé du nom de la méthode.

@Repository 
public interface PersonaRepository extends JpaRepository<Persona, Long> { 
    @Query("select p from Persona p") 
    List<NamesOnly> findAllOnlyNames(); 
} 

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.at-query

Redéfinition findAll() (même dans le cas improbable où il est possible) est probablement une mauvaise idée.

2

Vous êtes sur la bonne voie, votre findAll() est en conflit avec ceux spécifiés sur les interfaces Spring Data existantes et vous pouvez le renommer (comme vous l'avez essayé) mais il doit toujours être un nom compatible avec la requête mécanisme de dérivation.Essayez ceci:

@Repository 
public interface PersonaRepository extends JpaRepository<Persona, Long> { 
    List<NamesOnly> findAllOnlyNamesBy(); 
} 

This part of the Spring Data JPA documentation explique comment le processus de création de la requête fonctionne:

The mechanism strips the prefixes find…By , read…By , query…By , count…By , and get…By from the method and starts parsing the rest of it.

donc il vous suffit d'ajouter le mot-clé By au nom de la méthode, quoi que ce soit après ce mot-clé est traitée comme une condition , dans ce cas il n'y a pas de condition donc ça va tout chercher.

Pour désactiver la dérivation de requête à partir du nom de méthode, vous devez ajouter une annotation @Query(...) à la méthode et spécifier une requête JPA ou native à la place.