반응형
IN 절을 쓰다 만난 BadSqlGrammarException
Spring은 다양한 종류의 JdbcTemplate을 지원하는데 개인적으로는 NamedParameterJdbcTemplate를 애용하는 편이다. NamedParameterJdbcTemplate에서는 아래 예제처럼 WHERE ~ IN (~)을 편하게 사용할 수 있다.
public List<ProductEntity> findByIds(List<Long> productIds) {
final String query = "SELECT id, name, price, image_url FROM product WHERE id IN (:productIds)";
SqlParameterSource source = new MapSqlParameterSource("productIds", productIds);
return jdbcTemplate.query(query, source, ROW_MAPPER);
}
그런데 아래와 같은 오류와 마주치게 되었다. 요약하자면 SQL 문법이 잘못되었다는 뜻이다.
헌데 나는 이미 이 SQL이 잘 돌아가는 것을 확인했다. 테스트 코드도 잘 돌아갔다. 같은 우테코 크루인 이프가 List가 빈 값으로 들어온거 아니냐는 의문을 제시해주었다. 바로 아래와 같은 테스트 코드를 작성하였다.
@Test
void findByIds() {
List<ProductEntity> products = productDao.findByIds(new ArrayList<>());
assertThat(products).isEmpty();
}
결론부터 말하자면 이프 말이 맞았다.(땡큐^ㅡ^b) productIds가 빈 값으로 들어오는 경우에는 IN () 안에 아무런 값도 들어가지 않아 SQL 문법 오류가 발생한다. 다양한 해결 방법이 있겠지만 데이터가 없는 경우에는 빈 배열을 반환해야 한다고 생각했다. 아래와 같이 list에 대한 검증 코드를 추가해주었다.
public List<ProductEntity> findByIds(List<Long> productIds) {
if (productIds.isEmpty()) {
return new ArrayList<>();
}
final String query = "SELECT id, name, price, image_url FROM product WHERE id IN (:productIds)";
SqlParameterSource source = new MapSqlParameterSource("productIds", productIds);
return jdbcTemplate.query(query, source, ROW_MAPPER);
}
반응형
'Develop > Spring+JPA' 카테고리의 다른 글
모든 요구사항을 한 엔드포인트로 처리하는 방법 (2) | 2022.07.08 |
---|---|
[Spring] CORS 에러 해결하기 (0) | 2022.06.13 |
[Spring 5 프로그래밍 입문] chapter 5, 6 - 컴포넌트 스캔과 빈 라이프 사이클 (0) | 2022.06.04 |
[Spring Boot] 내가 설정하지 않아도 동작하는 어노테이션 (2) | 2022.05.28 |
[Spring] @Aspect는 컴포넌트 스캔 대상일까? (4) | 2022.05.25 |