Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como buscar registros de correspondência exata no Spring JPA @Query


Isso não é tão fácil porque o Hibernate/JPA tenta garantir que o modelo de entidade esteja em sincronia com o estado do banco de dados. Você aparentemente quer uma projeção que provavelmente não deve ser mantida em sincronia com o banco de dados. Se você realmente precisa fazer isso, pode usar a seguinte consulta, mas cuidado, pois isso pode causar a exclusão de elementos de serviço na coleção que não correspondem aos critérios:
@Query(value = "SELECT DISTINCT req FROM request req JOIN FETCH req.services srvs WHERE (srvs.status = :serviceStatus)")
List<Request> getAll(@Param("serviceStatus") String serviceStatus);

Isso geralmente é tratado com a introdução de DTOs e acho que esse é um caso de uso perfeito para Exibições de entidade de persistência em chamas .

Eu criei a biblioteca para permitir o mapeamento fácil entre modelos JPA e interface customizada ou modelos definidos por classes abstratas, algo como Spring Data Projections em esteróides. A ideia é que você defina sua estrutura de destino (modelo de domínio) da maneira que quiser e mapeie atributos (getters) por meio de expressões JPQL para o modelo de entidade.

Um modelo de DTO para seu caso de uso pode ter a seguinte aparência com 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();
    }
}

Consultar é uma questão de aplicar a visão de entidade a uma consulta, sendo a mais simples apenas uma consulta por id.

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

A integração do Spring Data permite que você o use quase como 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);

A melhor parte é que ele buscará apenas o estado realmente necessário!