티스토리 뷰
[Junit] @MybatisTest 에러 Invalid bound statement (not found) -feat. databaseId
메자곰 2022. 1. 13. 17:07org.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 설정 파일이 존재하고, 이를 테스트에 사용해야 할 경우 따로 지정해놓아야 한다라... 내부 동작을 정확히 모르니 해결은 했지만,, 다시 봐야 할 듯)
정리하면서, 이 게시글은 제공되지 않는 기술이라 안될 수도 있지만 대부분은 어떤 상황 하나가 맞춰지지 않아서 원하는 결과를 못 내는 경우가 많고 계속 해결방법을 찾는 과정을 수행해야겠다고 생각하며 작성하게 되었다 ㅎ
'개발 > 에러,이슈' 카테고리의 다른 글
[Javascript] forEach 안에서 return/break 처리? (0) | 2022.03.15 |
---|---|
[JUnit] mock 테스트시 호출 method 내부 local variable 값 확인하기 (0) | 2022.02.16 |
[lombok] IntelliJ @lombok 적용 안될때 (0) | 2021.08.29 |
[IntelliJ] git clone 후 intellij에서 spring project 정상 표현 안될때 (0) | 2021.08.29 |
[spring 주입 안됨] 멀티모듈-gradle 사용시 주입 안됨 이슈 (0) | 2021.04.14 |
- Total
- Today
- Yesterday
- 정렬
- Baekjoon
- sockjs
- 삼성 sw역량 테스트
- SWEA
- Heap
- MST
- 분리 집합
- Stomp
- 삼성 sw역량테스트
- dfs
- OS
- BFS
- websocket
- DP
- 채팅
- JavaScript
- Oracle
- Spring
- 백준
- 프로그래머스
- 알고리즘
- 코딩테스트
- 최소 스패닝 트리
- 완전탐색
- 운영체제
- java
- programers
- git
- 자바
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |