반응형
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): 메서드명 ~ 에러원인

 

에러 원인은 이전에 포스팅했던 글에서의 원인과 동일하기 때문에 아래 링크에서 참조하면 된다.

[마이바티스] MyBatis Mapped Statements collection does not contain value for ~ 에러

 

이번글에서는 에러가 어느 시점에 발생하며, 같은 원인임에도 불구하고 왜 이전과 다른 에러메시지가 출력되는가? 에 대해 이야기해보도록 하겠다.

 

MyBatis가 동작할때 내부적으로는 다음과 같은 코드 흐름이 일어난다.

 

초기화 시점에는 MyBatis가 매퍼 XML을 로드하여 mappedStatements 컬렉션만 구성할 뿐, Mapper파일의 namespace, ID 등의 매핑이 안된다거나 존재하지 않는 메서드까지 미리 검증하지 않는다.


따라서 이 시점에서는 초기화 자체가 실패하거나 에러 메시지가 곧장 출력되지 않고, 컬렉션이 단순히 “비어 있거나 일부만 채워진 상태”로 넘어가고, DAO 메서드를 실제로 호출하는 시점에야 비로소 “해당 ID의 매퍼 SQL이 있는지”를 확인하고, 없으면 최종적으로 BindingException("Invalid bound statement …")를 던지게 된다.

org.apache.ibatis.binding.MapperMethod.SqlCommand.Class

 

요약해 보면, DAO 호출 시점에 처음으로 키 존재 여부를 검사하고 그때 예외를 던지기 때문에, 초기화 단계에서는 별다른 에러가 없이 넘어갈 수 있다라고 이해하면 되겠다.


그러면 발생 원인은 똑같은데 에러 메시지가 "Mapped Statements collection ~"인 경우와 "Invalid bound statement ~"인 경우의 차이는 무엇인가?

 

결론부터 말하면 MyBatis의 버전에 따른 차이이다.

 

MyBatis 3.3.x 이하의 버전에서는 Configuration.getMappedStatement(...) 자체가 “Mapped Statements collection does not contain value for …” 예외를 던지도록 되어 있었다.
하지만 MyBatis 3.4.x 이상의 버전에서 내부 구현을 개선하면서, resolveMappedStatement(...) 메서드가 getMappedStatement(...) 호출 시 발생한 BuilderException을 직접 잡아서 null(mappedStatements.get(id)에 값이 없으면 null)을 리턴하도록 바뀌었고

org.apache.ibatis.session.Configuration.Class


그 결과 Configuration 단계에서 “Mapped Statements…” 메시지를 내지 않고, 곧바로 MapperMethod 단계까지 넘어와서 BindingException("Invalid bound statement…")만 던지도록 수정되었다.

 

요약하면 에러메시지에 “Invalid bound statement (not found): ~”만 보이는 이유는, 이미 내부에서 getMapped Statement(...) 예외를 잡아서 null 처리 후 오로지 BindingException 메시지만 남기도록 바뀐 버전의 MayBatis를 사용하고 있기 때문이라고 이해하면 된다.

 


글 내용 중 잘못된 부분이 있거나, 첨부하실 내용이 있으시면 댓글로 남겨주세요. 공부하는데 많은 도움이 됩니다.
-- 기억의 유효기간은 생각보다 짧다. --
반응형