Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment récupérer des enregistrements correspondants exacts dans Spring JPA @Query

Ce n'est pas si facile car Hibernate/JPA essaie de garantir que le modèle d'entité est synchronisé avec l'état de la base de données. Vous voulez apparemment une projection qui ne devrait probablement pas être synchronisée avec la base de données. Si vous devez vraiment le faire, vous pouvez utiliser la requête suivante, mais sachez que cela peut entraîner la suppression d'éléments de service dans la collection qui ne correspondent pas aux critères :

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

Ceci est généralement géré en introduisant des DTO et je pense que c'est un cas d'utilisation parfait pour Vues d'entité Blaze-Persistence .

J'ai créé la bibliothèque pour permettre une cartographie facile entre les modèles JPA et l'interface personnalisée ou les modèles définis par classe abstraite, quelque chose comme Spring Data Projections sur les stéroïdes. L'idée est de définir votre structure cible (modèle de domaine) comme vous le souhaitez et de mapper les attributs (getters) via des expressions JPQL au modèle d'entité.

Un modèle DTO pour votre cas d'utilisation pourrait ressembler à ce qui suit avec 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'interrogation consiste à appliquer la vue d'entité à une requête, la plus simple étant simplement une requête par identifiant.

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

L'intégration de Spring Data vous permet de l'utiliser presque comme 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 meilleure partie est qu'il ne récupérera que l'état réellement nécessaire !