티스토리 뷰

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)

mybatis 사용 시에 흔하게 만날 수 있는 에러로 인터넷에 검색하면 여러 해결방안들이 나온다. 나는 추가로 내가 겪은 특정 상황에서 뭐가 문제였는지 어떻게 해결했는지 남기려고 한다 ㅎ.. (스포 "databaseId", @ContextConfiguration)

 

먼저 일반적인 문제들 몇 개의 해결방안을 보자면,

해결방안 1 :

에러 코드에서도 볼 수 있듯이 binding이 안된다는 의미는 mapper인터페이스와 xml에서 뭔가 일치하지 않게 잘 못 썼을 수 있다는 의미이다.

 

예를 들면, 인터페이스의 메소드 명과 xml 쿼리에 id값이 오타로 인해 불일치한다던지, id값에 공백이 존재한다던지 하는 문제. → 인터페이스 메소드명 = xml id값 일치로 해결

//mapper interface
int insert(String s);

//mapper xml
<insert id="iinsert"></insert>

 

 

해결방안 2 : 

눈을 씻고 찾아도 오타가 없다면, 설정 문제일 가능성이 높다.

예를 들면, application.properties 에 아래와 같은 설정들을 제대로 해주지 않았다던가 빠트렸다던지 하는 문제. → 아래와 같이 설정 파일에 프로젝트 구성에 맞게 설정하는 것으로 해결

 

#application.properties 
#자신의 프로젝트에서 사용되는 쿼리가 담긴 xml 파일 경로 써주기
mybatis.mapper-locations = classpath:mybatis/mapper/**/*.xml 

#자신의 프로젝트에서 사용되는 mybatis.config.xml 파일 경로 써주기
mybatis.config-location = classpath:mybatis/mybatis.config.xml

 

이 두 가지 문제 외에도 다른 패키지에 같은 이름의 mapper가 존재한다던지 등등 사용하려고 하는 mapper가 잘 연결이 안 될만한 문제가 있을 때 발생한다.

 

 

 

여기서부터 내가 겪은 문제...

@MybatisTest에서의 문제 해결

나의 경우.. Junit5 @MybatisTest를 통해 mapper 테스트를 하던 중이었고, 다른 mapper 쿼리들을 잘 테스트를 하다가 특정 쿼리에서만 이 에러가 발생했다.. 즉, 위에서 언급한 문제들은 아닐 거라는 뜻

 

 

해결 과정 1 : 공통점 찾기

발생하는 특정 쿼리의 공통점은 "databaseId"를 설정해주었다는 점.

databaseId는 아래처럼 같은 id, 다른 databaseId 속성으로 테스트, 상용 등 사용되는 DB마다 다른 쿼리를 실행할 수 있도록 한다
//인터페이스 mapper
int insert();

//mapper.xml
<insert id="insert" databaseId="mysql">...</insert> //mysql DB사용할 때
<insert id="insert" databaseId="postgresql">...</insert> //postgresql DB사용할 때

 

해결 과정 2 : 공통점 다루기

databaseId 속성이 문제였고, 두 개 중 하나를 못 찾아서 그런가? 싶었다. databseId를 사용하기 위해선 config파일에 "DatabaseIdProvider"설정이 필요한데 아무리 봐도 제대로 설정되어 있다.

 

해결 과정 3 : 다른 상황에서 다뤄보기

@MybatisTest가 아니라 @SpringbootTest로 통합 테스트를 해봤다. 잘 수행된다.

실제로 application을 run 시켜서  수행해봤다. 잘 수행된다.

 

해결 과정 4 : 상황 종합하고 결론

@MybatisTest환경과 스프링 부트 통합 테스트와 실제 application 실행 환경에서 다른 점이 존재하는데, 그게 databaseId설정 파일을 찾지 못하는 것이라고 생각. → 그렇다면 설정 파일을 따로 지정해줘야 하나? 빙고.

 

 

앞서 말했던 것과 같이 databaseId를 사용하기 위해 DatabaseConfig.java파일에 따로 "DatabaseProvider"에 관한 내용을 설정해 놓은 상태였고 클래스단에 @ContextConfiguration을 사용해서 얘를 불러와야 테스트가 제대로 진행될 수 있었다.

 

 

해결

@ContextConfiguration(classes = {config 파일.class})

//혹은

@ContextConfiguration(locations = {경로/config 파일.xml})

 

 

추가로 SpringBoot 테스트에서 설정 파일이 지정되는 과정. @ContextConfiguration 얘가 생략되면 어떻게 수행되는지, auto configuration은 왜 안되는지, 되면 어디까지 되는 건지, 비슷한 기능을 하는 다른 어노테이션이 있는지, 통합 테스트와 다른 configuration 부분, Junit5,4에서의 차이점 등등을 시간 나면 봐 두면 좋을 것 같다...

(따로 지정된 mybatis 설정 파일이 존재하고, 이를 테스트에 사용해야 할 경우 따로 지정해놓아야 한다라... 내부 동작을 정확히 모르니 해결은 했지만,, 다시 봐야 할 듯)

 

 

 

 

 

정리하면서, 이 게시글은 제공되지 않는 기술이라 안될 수도 있지만 대부분은 어떤 상황 하나가 맞춰지지 않아서 원하는 결과를 못 내는 경우가 많고 계속 해결방법을 찾는 과정을 수행해야겠다고 생각하며 작성하게 되었다 ㅎ

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함