차근차근/Spring

executeQueryForObject returned too many results.

예쁜꽃이피었으면 2014. 7. 25. 23:57

이전에 글을 쓴 적이 있느나 같은 오류에 똑같이 당황을 해서

한번더 쓴다.

나의 경우엔 주소를 db에서 가져오는데 같은 값이 있어서

에러가 났다.

그래서 쿼리문에 DISTINCT 를 써서 중복을 없앴더니

에러도 사라졌다~

http://freeism.web-bi.net/tc/758 -(댓글남기려는데 자꾸 에러난다..)

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

http://blog.naver.com/PostView.nhn?blogId=saladin83&logNo=10104641363

쿼리가 문제거나 pk가 없어서 중복 레코드가 있는경우.

개발중 1건의 데이터 처리를 해놓고

실제 쿼리에선 2건 이상이 나올 경우.

 

 

http://minroom.tistory.com/19

말그래로..받는것 보다 넘어오는 값이 많을때 생기는 오류

리스트로 받아야하는 쿼리를 단일 받는거로 해놓아서 그럼

1. 쿼리 값이 어떻게 나오나 살펴보자

2. queryforList인가 확인해보자

반응형