해결된 질문
작성
·
329
0
@Bean
public JdbcPagingItemReader<RequestReportTargetDto> jdbcPagingItemReader() throws Exception {
HashMap<String, Object> parameters = new HashMap<>();
parameters.put("reqReportYn", "N");
return new JdbcPagingItemReaderBuilder<RequestReportTargetDto>()
.name("jdbcPagingItemReader")
.dataSource(dataSource)
.fetchSize(10)
.rowMapper(new BeanPropertyRowMapper<>(RequestReportTargetDto.class))
.pageSize(10)
.queryProvider(createQueryProvider())
.parameterValues(parameters)
.build();
}
@Bean
public PagingQueryProvider createQueryProvider() throws Exception {
SqlPagingQueryProviderFactoryBean qp = new SqlPagingQueryProviderFactoryBean();
qp.setDataSource(dataSource);
qp.setSelectClause("M_ID mId, SERVICE_NO serviceNo, SERVICE_TYPE serviceType, PRODUCT_CODE productCode, REQ_REPORT_YN reqReportYn");
qp.setFromClause("from TARGET_TEST");
qp.setWhereClause("where reqReportYn = :reqReportYn");
Map<String, Order> sortKeys = new HashMap<>();
sortKeys.put("mId", Order.ASCENDING);
qp.setSortKeys(sortKeys);
return qp.getObject();
}
@Getter @Setter
public class RequestReportTargetDto {
private String mId;
private String serviceNo;
private String serviceType;
private String productCode;
private String reqReportYn;
}
위와 같이 하고 실행하면 아래 오류가 납니다.
org.springframework.dao.InvalidDataAccessApiUsageException: No value supplied for the SQL parameter '_mId': No value registered for key '_mId'
at org.springframework.jdbc.core.namedparam.NamedParameterUtils.buildValueArray(NamedParameterUtils.java:379) ~[spring-jdbc-6.1.2.jar:6.1.2]
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.getPreparedStatementCreator(NamedParameterJdbcTemplate.java:472) ~[spring-jdbc-6.1.2.jar:6.1.2]
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.getPreparedStatementCreator(NamedParameterJdbcTemplate.java:446) ~[spring-jdbc-6.1.2.jar:6.1.2]
.....
sort key 로 정해준 값에서 계속 오류가 나는데 원인을 못찾고 있습니다.
sort key 를 바꾸면 바꾸는데로 앞에 _ 가 붙어서 위와 같은 오류가 납니다.
강사님이 디버깅할 때 찍어주신 것처럼 where 절에 sort key 가 추가가 되는데 거기서 오류가 나는 것 같습니다.
수정해봐야 하거나 더 확인할 수 있는 부분이 있을까요??
답변 2
1
네
코드상에는 특별한 문제가 없어보이는데요..
혹시 이렇게 해보십시오
qp.setSelectClause("M_ID, SERVICE_NO serviceNo, SERVICE_TYPE serviceType, PRODUCT_CODE productCode, REQ_REPORT_YN reqReportYn");
...
Map<String, Order> sortKeys = new HashMap<>();
sortKeys.put("M_ID", Order.ASCENDING);
별칭을 하지 않고 했을 때 정상적으로 동작하는지 해 보시고 만약 정상동작한다면 별칭 쪽을 들여다 보셔야 할 것 같습니다.
계속 오류가 난다면 컬럼명 관련 여러 테스트를 해 보시면서 오류를 잡아내야 할 것 같습니다.
코드 상으로는 특별한 문제가 없어 보이지만 컬럼명의 별칭에 있어 예기치 못한 오류가 숨어 있을 수 있습니다
1
안녕하세요, 인프런 AI 인턴입니다.
질문해주신 내용을 바탕으로 문제를 살펴보면 PagingQueryProvider
에서 정렬 키를 설정하는 부분에 문제가 있는 듯 합니다. 정렬 키의 값으로 mId
를 사용하셨는데, JdbcPagingItemReader
를 사용할 때 내부적으로 생성되는 쿼리에 파라미터로 _mId
가 추가되었고, 이에 대한 바인딩 값을 찾지 못해 InvalidDataAccessApiUsageException
예외가 발생한 것으로 보입니다.
해당 문제를 해결하기 위해 확인해볼 수 있는 몇 가지 조치를 제안 드립니다.
SqlPagingQueryProviderFactoryBean
객체가 쿼리를 생성할 때 정렬 키의 이름에 언더스코어 _
가 붙는 이유를 확인해보세요. 이는 PagingQueryProvider
가 내부적으로 사용하는 네이밍 규칙일 수 있습니다. 때로는 언더스코어를 붙여 사용하는 것이 필요할 수 있지만, 경우에 따라 이로 인한 문제가 발생할 수 있습니다.
정렬 키를 설정할 때, 정렬 키의 이름 뿐만 아니라 해당 필드가 실제 데이터베이스의 컬럼과 일치하는지도 검토해봐야 합니다. 컬럼 이름과 DTO의 필드 이름은 대소문자를 포함하여 정확히 일치해야 합니다.
namedParameterJdbcTemplate
를 사용하는 경우 해당 템플릿이 사용하는 쿼리 파라미터의 값을 등록해줘야 합니다. parameterValues
메소드를 통해 전달한 파라미터 값 외에도 정렬 키에 해당하는 파라미터 값도 등록해주어야 할 수 있습니다.
이 외에도 정렬 키를 사용하여 ORDER BY
절을 구성할 때 적절한 컬럼 이름과 정렬 방법(ASC 또는 DESC)을 제공하는 것이 쿼리가 올바르게 실행되도록 하는 중요한 요소입니다.
정렬 키 문제가 계속 발생한다면, 직접 쿼리를 작성하여 사용하는 방식으로 임시 조치를 취할 수도 있습니다. 단, PagingQueryProvider
를 사용하여 페이징 기능을 구현하려는 목적과 프로젝트 상의 요구사항을 고려하여 적절한 해결 방법을 선택해야 할 것입니다.
위 방법들로 문제가 해결되지 않는 경우, 추가적인 로깅을 통해 내부적으로 생성되는 쿼리와 파라미터 바인딩 과정을 확인해볼 필요가 있으며, 필요하다면 PagingQueryProvider
구현체의 동작 방식에 대해 더 깊이 파악하거나 스프링 프레임워크에 대한 추가 문서를 참조해야 할 수도 있습니다.
참고로 스프링 데이터 문서의 예제 코드를 참조하실 수 있는 링크를 함께 드리니, 참조하시어 문제 해결에 도움이 되시길 바랍니다.
이러한 점들을 확인해보시고, 이후에도 동일한 문제가 발생한다면 구체적인 쿼리와 함께 추가적인 질문을 주시면 답변을 드리도록 하겠습니다.
sort 랑 where 에 들어가는 값을 테이블 컬럼명이랑 똑같이 대문자로 하니까 됩니다.
안돼서 한참 헤맸는데ㅠ 알려주신대로 하니 바로 해결됐어요 ㅎㅎ 감사합니다!!!