Mysql
 sql >> Database >  >> RDS >> Mysql

Come recuperare i record corrispondenti esatti in Spring JPA @Query

Non è così facile perché Hibernate/JPA cerca di garantire che il modello di entità sia sincronizzato con lo stato del database. Apparentemente vuoi una proiezione che molto probabilmente non dovrebbe essere sincronizzata con il database. Se proprio devi farlo, puoi utilizzare la seguente query, ma attenzione che ciò potrebbe causare l'eliminazione di elementi di servizio nella raccolta che non corrispondono ai criteri:

@Query(value = "SELECT DISTINCT req FROM request req JOIN FETCH req.services srvs WHERE (srvs.status = :serviceStatus)")
List<Request> getAll(@Param("serviceStatus") String serviceStatus);

Questo di solito viene gestito introducendo DTO e penso che questo sia un caso d'uso perfetto per Visualizzazioni entità Blaze-Persistence .

Ho creato la libreria per consentire una facile mappatura tra i modelli JPA e l'interfaccia personalizzata o modelli definiti da classi astratte, qualcosa come Spring Data Projections su steroidi. L'idea è di definire la struttura di destinazione (modello di dominio) nel modo che preferisci e di mappare gli attributi (getter) tramite espressioni JPQL al modello di entità.

Un modello DTO per il tuo caso d'uso potrebbe essere simile al seguente con Blaze-Persistence Entity-Views:

@EntityView(Request.class)
public interface RequestDto {
    @IdMapping
    Integer getId();
    String getStatus();
    @Mapping("services[status = :serviceStatus]")
    Set<ServiceDto> getServices();

    @EntityView(Service.class)
    interface ServiceDto {
        @IdMapping
        Integer getId();
        Integer getRequestId();
        String getStatus();
    }
}

L'esecuzione di query consiste nell'applicare la vista entità a una query, la più semplice è solo una query per id.

RequestDto a = entityViewManager.find(entityManager, RequestDto.class, id);

L'integrazione Spring Data ti consente di usarlo quasi come Spring Data Projections:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

List<RequestDto> findAll(@OptionalParam("serviceStatus") String serviceStatus);

La parte migliore è che recupererà solo lo stato effettivamente necessario!