Spring

sql 기본 쿼리 결과를 spring jpa 저장소의 DTO에 매핑하는 방법은 무엇입니까?

기록만이살길 2022. 11. 13. 20:31
반응형

sql 기본 쿼리 결과를 spring jpa 저장소의 DTO에 매핑하는 방법은 무엇입니까?

1. 질문(문제점):

안녕하세요, 제가 달성하려는 것은 SQL 네이티브 쿼리 결과 맵을 Java spring jpa 리포지토리의 DTO로 가져오는 것입니다. 이 작업을 제대로 수행하려면 어떻게 해야 합니까? 여러 코드를 시도했지만 작동하지 않습니다. 시도한 내용은 다음과 같습니다.

첫 시도 :

@Repository
public interface StockRepository extends RevisionRepository<Stock, Long, Integer>, JpaRepository<Stock, Long> {
    
   @Query(value = "SELECT stock_akhir.product_id AS productId, stock_akhir.product_code AS productCode, SUM(stock_akhir.qty) as stockAkhir "
        + "FROM book_stock stock_akhir "
        + "where warehouse_code = (:warehouseCode) "
        + "AND product_code IN (:productCodes) "
        + "GROUP BY product_id, product_code, warehouse_id, warehouse_code", nativeQuery = true)
   List<StockAkhirDto> findStockAkhirPerProductIn(@Param("warehouseCode") String warehouseCode, @Param("productCodes") Set<String> productCode);
}

함수를 실행하면 다음 오류가 발생합니다.

[org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] 유형에서 [com.b2bwarehouse.Dto.RequestDto.StockDto.StockAkhirDto] 유형으로 변환할 수 있는 변환기를 찾을 수 없습니다.

두 번째 시도:

@Repository
public interface StockRepository extends RevisionRepository<Stock, Long, Integer>, JpaRepository<Stock, Long> {
    
   @Query(value = "SELECT new com.b2bwarehouse.Dto.RequestDto.StockDto.StockAkhirDto(stock_akhir.product_id AS productId, stock_akhir.product_code AS productCode, SUM(stock_akhir.qty) as stockAkhir) "
      + "FROM book_stock stock_akhir "
      + "where warehouse_code = (:warehouseCode) "
      + "AND product_code IN (:productCodes) "
      + "GROUP BY product_id, product_code, warehouse_id, warehouse_code", nativeQuery = true)
   List<StockAkhirDto> findStockAkhirPerProductIn(@Param("warehouseCode") String warehouseCode, @Param("productCodes") Set<String> productCode);
}

두 번째로 여기에 오류가 있습니다.

ResultSet을 추출할 수 없습니다. SQL [해당 사항 없음]; 중첩 예외는 org.hibernate.exception.SQLGrammarException입니다: ResultSet을 추출할 수 없습니다

아래는 내 DTO입니다.

@Data
@AllArgsConstructor
@NoArgsConstructor
public class StockAkhirDto {
   private Long productId;
   private String productCode;
   private Integer stockAkhir;
}

코드를 수정하려면 어떻게 해야 합니까? 결과를 내 DTO에 가져올 수 있습니까?

2. 해결방안:

적절한 SQL 결과 집합 매핑을 사용하여 다음과 같은 명명된 기본 쿼리를 정의할 수 있습니다.

import javax.persistence.NamedNativeQuery;
import javax.persistence.SqlResultSetMapping;
import javax.persistence.ConstructorResult;
import javax.persistence.ColumnResult;

@Entity
@NamedNativeQuery(
    name = "find_stock_akhir_dto",
    query =
        "SELECT " + 
        "  stock_akhir.product_id AS productId, " + 
        "  stock_akhir.product_code AS productCode, " + 
        "  SUM(stock_akhir.qty) as stockAkhir " + 
        "FROM book_stock stock_akhir " + 
        "where warehouse_code = :warehouseCode " + 
        "  AND product_code IN :productCodes " + 
        "GROUP BY product_id, product_code, warehouse_id, warehouse_code",
    resultSetMapping = "stock_akhir_dto"
)
@SqlResultSetMapping(
    name = "stock_akhir_dto",
    classes = @ConstructorResult(
        targetClass = StockAkhirDto.class,
        columns = {
            @ColumnResult(name = "productId", type = Long.class),
            @ColumnResult(name = "productCode", type = String.class),
            @ColumnResult(name = "stockAkhir", type = Integer.class)
        }
    )
)
public class SomeEntity
{
}

그런 다음 사용하십시오.

@Repository
public interface StockRepository extends RevisionRepository<Stock, Long, Integer>, JpaRepository<Stock, Long> {

   @Query(name = "find_stock_akhir_dto", nativeQuery = true)
   List<StockAkhirDto> findStockAkhirPerProductIn(
      @Param("warehouseCode") String warehouseCode,
      @Param("productCodes") Set<String> productCode
   );
}
반응형