ibatis를
사용할 때, 간혹 DB에 원하는 데이터가 없으면 어떡하지?라는 생각이 들 때가 있다.
대부분의 경우 문제가 없겠지만, 다른 사람의
코드를 보다가 궁금함에 검색했다.
먼저 queryForObject()를 사용하는 경우 null을 리턴한다.
그냥
단순하게 생각을 해도, 데이터가 없는 경우 어떤 Object를 리턴해야 하는지 애매하다.
실제로 코드를 보면, result row가 많은
경우 exception, 1개인 경우는 리턴, 없으면 null을
리턴한다.
MappedStatement.java
[code]public Object
executeQueryForObject(StatementScope statementScope,
Transaction trans, Object parameterObject, Object resultObject)
throws SQLException {
try {
Object object = null;
DefaultRowHandler rowHandler = new DefaultRowHandler();
executeQueryWithCallback(statementScope, trans.getConnection(),
parameterObject, resultObject, rowHandler,
SqlExecutor.NO_SKIPPED_RESULTS,
SqlExecutor.NO_MAXIMUM_RESULTS);
List list =
rowHandler.getList();
if (list.size() > 1) {
throw new SQLException(
"Error: executeQueryForObject
returned too many results.");
} else if (list.size() > 0) {
object = list.get(0);
}
return object;
} catch (TransactionException e) {
throw new
NestedSQLException(
"Error getting Connection from Transaction.
Cause: " + e, e);
}
}[/code]
하지만
queryForList()를 사용하는 경우 empty list가 리턴된다.
리스트의 경우에는 명확하게 List이기
때문일까?
결국 DefaultRowHandler의 값을 리턴하는데 이 객체의 초기값이 new
ArrayList()이다.
[code]public List executeQueryForList(StatementScope
statementScope,
Transaction trans, Object parameterObject, int
skipResults, int maxResults)
throws SQLException {
try {
DefaultRowHandler rowHandler = new DefaultRowHandler();
executeQueryWithCallback(statementScope, trans.getConnection(),
parameterObject, null, rowHandler, skipResults, maxResults);
return
rowHandler.getList();
} catch (TransactionException e) {
throw
new NestedSQLException(
"Error getting Connection from
Transaction. Cause: " + e, e);
}
}[/code]
DefaultRowHandler.java
[code]public class
DefaultRowHandler implements RowHandler {
private List list = new
ArrayList();
public void handleRow(Object valueObject) {
list.add(valueObject);
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
}[/code]
여튼
queryForList()를 사용하는 경우, (result != null) 방식으로 체크를 하면 오류가 발생할 것이다.
나같은
경우에 그동안 문제가 없었던 것은 CollectionUtils.isNotEmpty()를 사용했기 때문이다.
이래서 코딩도 평소
습관이 중요하다는 생각이 든다.
참고 : http://blog.naver.com/PostView.nhn?blogId=tykim00&logNo=90086378689
이전에 글을 쓴 적이 있느나 같은 오류에 똑같이 당황을 해서
한번더 쓴다.
나의 경우엔 주소를 db에서 가져오는데 같은 값이 있어서
에러가 났다.
그래서 쿼리문에 DISTINCT 를 써서 중복을 없앴더니
에러도 사라졌다~
http://freeism.web-bi.net/tc/758 -(댓글남기려는데 자꾸 에러난다..)
http://blog.naver.com/PostView.nhn?blogId=saladin83&logNo=10104641363
쿼리가 문제거나 pk가 없어서 중복 레코드가 있는경우.
개발중 1건의 데이터 처리를 해놓고
실제 쿼리에선 2건 이상이 나올 경우.
말그래로..받는것 보다 넘어오는 값이 많을때 생기는 오류
리스트로 받아야하는 쿼리를 단일 받는거로 해놓아서 그럼
1. 쿼리 값이 어떻게 나오나 살펴보자
2. queryforList인가 확인해보자
반응형
'차근차근 > Spring' 카테고리의 다른 글
server tomcat v7.0 server at localhost failed to start. 2 (0) | 2015.06.01 |
---|---|
Server Tomcat v7.0 Server at localhost failed to start. 1 (0) | 2015.06.01 |
spring + maven + eclipse (0) | 2015.05.21 |
controller에서 alert (0) | 2014.07.26 |
com.ibatis.common.jdbc.exception.NestedSQLException (0) | 2014.07.25 |