간단하게 DAO를 구현할 일이 생겼다.

spring에 JdbcTemplate를 사용하는 것이 편할거 같아서 이용을 하고 있다.

근데, ResultSet이 없으면  org.springframework.dao.EmptyResultDataAccessException이 발생을 한다.

지라에 등록이 되어 있는데, 오픈이 되어있네.
http://jira.springframework.org/browse/SPR-5294

덧~ 위에 지라에 나온 것은 DB2에 대한 얘기이다.


대략 예외 메세지는 다음과 같다.

org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0
at org.springframework.dao.support.DataAccessUtils.requiredSingleResult(DataAccessUtils.java:71)
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:722)
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:732)
at org.springframework.jdbc.core.simple.SimpleJdbcTemplate.queryForObject(SimpleJdbcTemplate.java:151)
at com.twc.ivr.dao.AccountProfileDaoImpl.findAccount(AccountProfileDaoImpl.java:107)

API를 살펴보니 별 내용이 없다.
http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/dao/EmptyResultDataAccessException.html

그래서 다음과 같이 해결을 했다.

try {
       return (Blog)jdbcTemplate.queryForObject(sql, new Object[] { url }, mapper) ;
} catch (EmptyResultDataAccessException e) {
   return null;
}

구글에서 검색을 해보면. 위와 같은 이유로 고생하는 사람들이 꽤 많다.
http://www.google.co.kr/search?complete=1&hl=ko&newwindow=1&q=JdbcTemplate++org.springframework.dao.EmptyResultDataAccessException&btnG=%EA%B2%80%EC%83%89&lr=&aq=f&oq=

.html 예외는 http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/dao/EmptyResultDataAccessException.html를 서브클래스로 구현되었다.


영회님이 API링크를 줘서 다시 잘 살펴보니 관련 내용이 있다.

queryForObject

public Object queryForObject(String sql,
                             RowMapper rowMapper)
                      throws DataAccessException
Description copied from interface: JdbcOperations
Execute a query given static SQL, mapping a single result row to a Java object via a RowMapper.

Uses a JDBC Statement, not a PreparedStatement. If you want to execute a static query with a PreparedStatement, use the overloaded queryForObject method with null as argument array.

Specified by:
queryForObject in interface JdbcOperations
Parameters:
sql - SQL query to execute
rowMapper - object that will map one object per row
Returns:
the single mapped object
Throws:
IncorrectResultSizeDataAccessException - if the query does not return exactly one row
DataAccessException - if there is any problem executing the query
See Also:
JdbcOperations.queryForObject(String, Object[], RowMapper)
위에 내용에 대해서 덧글을 달아주신 분들이 이야기들을 정리해보면, queryForObject는 하나의 row만 리턴하는 API이고, 쿼리에 만족하는 값이 없으면  IncorrectResultSizeDataAccessException의 sub 클래스인 EmptyResultDataAccessException를 발생한다. 이것은 버그는 아니고 API를 개발한 사람의 의도라는 것이다. 2row이상의 데이터도 아니고 0row를 리턴할때 예외를 발행하는 것은 도데체 알수 없는 의도이다. 어떤 이득을 얻으려고 했을까?

권남님은 그래서 queryForList를 사용하라고 하는데, 내 생각은 하나의 row면 queryForObject를 사용하고 예외처리로 널을 리턴하는 것이 더 좋아보인다. collection이 아닌 데이터를 1개 리턴을 할때 예외가 난다고 리스트로 collection으로 가져온다는 것은 좀 이상하다. 코드에서 의도를 볼때 queryForObject vs queryForList를 사용하는 것은 의미적 차이가 크다.

http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/jdbc/core/JdbcTemplate.html

트랙백 보낼 주소 :: http://www.ologist.co.kr/trackback/919

댓글을 달아주세요:: 네티켓은 기본, 스팸은 사절

  1. 2008/11/27 13:45
    댓글 주소 수정/삭제 댓글
    지적하신 내용은 API에 설명이 나와 있습니다.
    http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/jdbc/core/JdbcTemplate.html#queryForObject(java.lang.String,%20java.lang.Object[],%20java.lang.Class)

    그리고 JIRA에 오른 것은 다른 내용이네요. 특정 DB를 사용하는 경우 queryForObject 가 API 대로 작동하지 않는다는 것이죠.
    • 2008/11/28 01:17
      댓글 주소 수정/삭제
      제가 잘못된 버젼의 링크를 달았네요. API에 뭐가 나와있다는 거죠?
      지라에 나온 내용은 DB2이긴 한데, 제가 사용하는 MSSQL에서도 안되네요.
  2. 권남
    2008/11/28 13:51
    댓글 주소 수정/삭제 댓글
    버그가 아니라 원래 의도적으로 결과가 정확히 1 일 경우에만 작동하도록 만들어진 메소드입니다. 영회님이 말씀하신건 그에 대한 내용이 API DOC에 나와 있다는 얘기구요. queryForObject API DOC의 예외 부분을 살펴보세요.
    따라서 결과를 받을때 List 형태로 반환하는 메소드를 사용해야 합니다.
    그리고 나서는 http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/dao/support/DataAccessUtils.html#singleResult(java.util.Collection) 를 사용하여 0이면 null, 1이면 해당 값, 2 이상이면 예외를 발생시키도록 처리합니다.
    • 2008/11/30 12:04
      댓글 주소 수정/삭제
      답변 감사합니다. 다시 천천히 살펴보니 내용이 있네요.
    • 2008/11/30 20:13
      댓글 주소 수정/삭제
      예외가 발생한다고 하나의 데이터를 가져올때 list를 사용하는 것은 좀 이상하네요..^^; 그냥 queryForObject를 사용하고 예외처리를 해주는 것이 나을듯...1row데이터만 만족해서 리턴하고 널인 경우 예외를 던지게 만든 API의 의도는 잘모르겠네요. 무슨 의도일까요?
  3. 권남
    2008/11/28 13:55
    댓글 주소 수정/삭제 댓글
    http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/dao/support/DataAccessUtils.html#uniqueResult(java.util.Collection) 이메 맞을거 같네요. 둘 차이가 뭔지 사실 잘 모르겠네요.. single과 unique라...

◀ PREV : [1] : ... [17] : [18] : [19] : [20] : [21] : [22] : [23] : [24] : [25] : ... [649] : NEXT ▶

BLOG main image
OOP and Java by ologist

공지사항

카테고리

All (649)
private!! (106)
WEB & IT (140)
Developer (400)