본문 바로가기
Develop/Spring+JPA

WHERE절 IN과 NamedParameterJdbcTemplate

by 연로그 2022. 6. 8.
반응형

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);
}
반응형