예외 요약
org.mybatis.spring.MyBatisSystemException:
nested exception is org.apache.ibatis.exceptions.TooManyResultsException:
Expected one result (or null) to be returned by selectOne(), but found: 246
문제 요약
항목 | 내용 |
---|---|
원인 | selectOne() 호출 시 결과가 2개 이상 반환됨 |
기대값 | 0개 또는 1개 |
실제값 | 246개 |
영향 | 서비스 응답 실패, 예외 전파 |
오류 발생 조건
sqlSession.selectOne("namespace.methodName", param);
- 이 쿼리는 정확히 1개의 결과만 기대해야 합니다.
- 결과가 2개 이상이면 TooManyResultsException이 발생합니다.
실무자가 자주 놓치는 포인트
쿼리 결과 조건이 불명확
- WHERE 절 조건이 느슨해 중복을 제거하지 못한 경우
- 예: country_code = 'KR'만 사용 → 다수 레코드 가능
DB 테이블 중복 데이터
- 논리적으로 유일해야 할 데이터가 중복되어 있을 수 있음
- 인덱스 또는 UNIQUE 제약 조건이 누락된 경우 확인 필요
selectOne()을 써야 할지 재검토
- 애초에 다건 결과가 예상되는 쿼리를 단건 조회로 처리한 경우
해결 방안
- 쿼리 수정 – 결과를 하나로 제한
SELECT *
FROM COUNTRY
WHERE CODE = 'KR'
FETCH FIRST 1 ROW ONLY
또는 ORDER BY 정렬 기준을 추가해 가장 적절한 1건만 반환되도록 구성합니다.
- 메서드 변경 – selectList()로 다건 결과 처리
List
→ 호출 메서드가 selectList()로 바뀌면 예외가 발생하지 않고, 반복문 등으로 처리 가능해집니다.
- 데이터 검증
- SQL 쿼리를 직접 실행해 결과 row 수를 확인해보세요.
- 논리적 유일 조건을 충족하지 못하는 데이터가 있는 경우, 먼저 DB 정비가 필요합니다.
실무 팁
“A사는 이 문제로 매번 수동으로 selectOne 예외를 수습해야 했고, QA 단계에서도 오류 발생률이 높았음 → 단건 보장 쿼리에 대해 테스트케이스 강화하고, 다건 쿼리는 selectList로 전환하면서 재발 방지.”
추가 정보
- MyBatis에서 selectOne은 결과가 많을 때 예외를 발생시켜 디버깅을 돕는 설계입니다.
- XML Mapper 파일에서 resultType이 잘못 지정된 경우도 원인일 수 있습니다.
마무리
selectOne()은 단일 행 반환이 확실한 쿼리에서만 사용해야 합니다.
쿼리 조건이 애매하거나 데이터 정합성이 보장되지 않으면 반드시 쿼리 수정 또는 메서드 교체를 검토해야 합니다.
“배포 전 설정 유효성 검사는 단순 실수로 인한 전체 장애를 방지할 수 있습니다.”