es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Resultado de la consulta nativa no se establece correctamente en la clase de proyección.

Estoy tratando de ingresar el resultado de una consulta nativa en una proyección. Pero parece que los valores del resultado de la consulta no se asignan correctamente a los campos adecuados en el objeto de proyección.

Mi consulta nativa es algo como esto:

@Query(value = "select p.siteId,"
        + " sum(case when p.arrivalDate = :date then 1 else 0 end) as arrivalTotal "
        + " sum(case when p.departureDate = :date then 1 else 0 end) as departureTotal "
        + " from product p "
        + " where p.collectionSite = :siteId"
        + " and (p.arrivalDate = :date or p.departureDate = :date)", nativeQuery = true)
List<deliverysummary> getDeliverySummary(@Param("siteId") String siteId,
        @Param("date") String date);

Mi clase de proyección es:

public interface DeliverySummary {
    String getSiteId();
    String getArrivalTotal();
    String getDepartureTotal();
}

Los resultados se devolverían así:

siteId = 5 (cuando debería ser site1)
arrivalTotal = "site1" (cuando debería ser 2)
departureTotal = 2 (cuando debería ser 5)

Sospecho que el problema se debe a que los campos en el objeto de proyección no son campos nativos de la tabla (y la entidad), que son sumas. ¿Hay alguna manera de establecer esto correctamente? Gracias de antemano.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, el problema es que los campos en el objeto de proyección no están mapeados directamente a los campos de resultado de la consulta nativa. Para establecer adecuadamente los valores en el objeto de proyección, puedes utilizar la anotación @SqlResultSetMapping para mapear el conjunto de resultados a los campos en la clase de proyección. Aquí tienes un ejemplo:

    @SqlResultSetMapping(
       name = "DeliverySummaryMapping",
       classes = {
          @ConstructorResult(
             targetClass = DeliverySummary.class,
             columns = {
                @ColumnResult(name = "siteId", type = String.class),
                @ColumnResult(name = "arrivalTotal", type = String.class),
                @ColumnResult(name = "departureTotal", type = String.class)
             }
          )
       }
    )
    
    @Query(value = "select p.siteId,"
            + " sum(case when p.arrivalDate = :date then 1 else 0 end) as arrivalTotal "
            + " sum(case when p.departureDate = :date then 1 else 0 end) as departureTotal "
            + " from product p "
            + " where p.collectionSite = :siteId"
            + " and (p.arrivalDate = :date or p.departureDate = :date)", nativeQuery = true)
    @SqlResultSetMapping(name="DeliverySummaryMapping")
    List<deliverysummary> getDeliverySummary(@Param("siteId") String siteId,
            @Param("date") String date);
    

    En este ejemplo, definimos un nuevo @SqlResultSetMapping llamado DeliverySummaryMapping que mapea el conjunto de resultados a los campos en la clase de proyección DeliverySummary. Utilizamos @ColumnResult para mapear cada campo en la clase de proyección con la columna correspondiente en el conjunto de resultados.

    Luego, aplicamos el @SqlResultSetMapping al método de consulta utilizando el atributo name para especificar el mapeo a utilizar.

    Con esta configuración, el conjunto de resultados debería mapearse correctamente a los campos en el objeto de proyección.

Comments are closed.