[Spring Boot] Far restituire una projection ad un custom JpaRepository

di il
3 risposte

[Spring Boot] Far restituire una projection ad un custom JpaRepository

Ciao a tutti.
Avrei la necessità (in realtà è più un desiderio, che una reale necessità) di far restituire ad un JPA Repository di Spring Boot una lista di projections derivante da una custom query realizzata all'interno dell'implementazione di un custom repository.

Mi spiego meglio.
Ho la mia entity (chiamiamola Persona).
Ho definito la mia projection (chiamiamola PersonaSemplice) che espone solo una parte dei campi di Persona (ovvero è una interface).
Ho, quindi, il mio JpaRepository al cui interno posso usare tranquillamente la mia projection:

public interface PersonaRepository extends JpaRepository<Persona, Integer> {
   ... // vari metodi

   @Query("SELECT p FROM Persona p ORDER BY p.cognome")
   List<PersonaSemplice> getPersoneSemplificato();
}
Fin qui nessun problema: Spring Boot effettua automaticamente il proxy tra l'entity Persona e la projection PersonaSemplice.

Ora nasce l'esigenza di eseguire una query un po' più articolata, tale che l'annotation @Query non è più sufficiente; ho la necessità, quindi, di definire un Repository custom. Definisco, quindi la mia nuova interfaccia:

public interface PersonaRepositoryCustom {
   List<PersonaSemplice> getPersoneSemplificatoConSpecifiche( ... );
}
Aggiorno il PersonaRepository:

public interface PersonaRepository extends JpaRepository<Persona, Integer>, PersonaRepositoryCustom {
   ...
}
E implemento la mia nuova interfaccia:

public class PersonaRepositoryCustomImpl implements PersonaRepositoryCustom {
   @PersistenceContext
   EntityManager em;

   @Override
   public List<PersonaSemplice> getPersoneSemplificatoConSpecifiche( ... ) {
      // Eseguo la mia query articolata, usando l'EntityManager
      StringBuilder sql = new StringBuilder();
      sql.append("SELECT p FROM Persona p WHERE ...");
      ... // Aggiungo determinate condizioni in funzione dei parametri passati
      ... // Altre specifiche di ritorno massimo, ecc.

      TypedQuery<PersonaSemplice> qry = em.createQuery(sql, PersonaSemplice.class);
      ...
      return qry.getResultList();
   }
E qui, ovviamente, nasce il problema: PersonaSemplice non è una Entity, quindi non la posso usare per tipizzare la TypedQuery (se ci si prova, si ottiene una "IllegalArgumentException: Type specified for TypedQuery is incompatible with the query return type", che è ovvia: la query fa riferimento ad una entity "Persona", mentre la TypedQuery è stata tipizzata con una interface).

Da qui la domanda: come posso ottenere che Spring Boot effettui il proxy dalla entity alla projection (come fa normalmente in automatico) quando ho una custom query come definito sopra? Sempre se è possibile, altrimenti fa nulla, lavoro direttamente con le entity.

Grazie per qualunque info.

3 Risposte

  • Re: [Spring Boot] Far restituire una projection ad un custom JpaRepository

    SpiritoLibero ha scritto:


    Da qui la domanda: come posso ottenere che Spring Boot effettui il proxy dalla entity alla projection (come fa normalmente in automatico) quando ho una custom query come definito sopra? Sempre se è possibile, altrimenti fa nulla, lavoro direttamente con le entity.
    Una projection in JPQL con una classe DTO (quindi non un Object[] ) se non sbaglio si fa con questa forma, es.:

    SELECT new x.y.z.LibroDTO(l.titolo, l.pagine) FROM Libro l WHERE ........

    Dove LibroDTO deve essere una classe e quanto si passa tra ( ) deve chiaramente corrispondere ad un costruttore.
  • Re: [Spring Boot] Far restituire una projection ad un custom JpaRepository

    Ciao andbin. Sì, quella è una possibilità, avendo una classe che rappresenta la projection... che io non ho perchè al momento delego a Spring Boot la cosa tramite i suoi proxy automatici. Speravo che Spring Boot potesse farlo in automatico (come già fa, del resto) utilizzando la interface che ho già preparato (e che uso per altri metodi), senza dovermi sobbarcare anche la scrittura della classe, ma se non ci sono alternative, pazienza... non muore nesuno.
  • Re: [Spring Boot] Far restituire una projection ad un custom JpaRepository

    SpiritoLibero ha scritto:


    Sì, quella è una possibilità, avendo una classe che rappresenta la projection... che io non ho perchè al momento delego a Spring Boot la cosa tramite i suoi proxy automatici.
    Le projection basate su interfacce sono possibili con Spring Data JPA, è anche documentato: Interface-based Projections
    Ma questo vale sicuramente solo se usi Spring Data JPA. Se usi direttamente il EntityManager ... quello è JPA puro (non Spring Data JPA) e lì non mi pare proprio che JPA faccia alcun tipo di proxying.
Devi accedere o registrarti per scrivere nel forum
3 risposte