요약
UnsatisfiedDependencyException 라고 검색하면 마땅한 해결법이 나오지 않으니 그 이후에 나오는 "Caused by", "Cause" 바로 직후에 나오는 Exception을 유심히 보자.
Mapped Statements collection already contains value for 에러는 매핑 과정에서 이미 등록된 값이 존재할 때 발생하는 에러이다. 나는 id 속성값이 중복되는 게 있어서 생긴 오류였다. 따라서 중복되지 않게 id 속성값을 바꿔 주었더니 문제가 해결되었다.
해결 과정
Spring을 사용하다가 아래와 같은 오류가 발생했다. 그리고 페이지에는 HTTP 404 오류가 발생했다.
bookServiceImpl : Service 인터페이스를 상속받는 Service class (@Service 설정)
repo : BookRepo라는 Book(DTO)를 주고받는 DAO interface 타입의 bookServiceImpl 필드명
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'bookServiceImpl':
Unsatisfied dependency expressed through field 'repo';
(...생략...)
UnsatisfiedDependencyException으로 오류를 검색해보니 마땅한 해결책을 얻지 못했다.
StackOverflow를 살펴보니 보통 Caused by: 다음 부분이 오류 해결의 핵심이 되는 부분이더라.
긴 에러 메시지를 주욱 읽어보니 다음 메시지가 에러의 핵심임을 알게 되었다.
Cause라고 적혀 있길래 유심이 읽어 보았다.
Cause: java.lang.IllegalArgumentException:
Mapped Statements collection already contains value for (패키지명).BookRepo.select.
> Exception 해석 : 이미 for 이후 파일에 Mapped Statements collection이 이미 존재한다.
> 원인 : for 이후의 파일에 같은 이름의 method가 존재해서 myBatis가 예외를 던진 것이라고 한다. 즉, 작업이 중복되는 게 있기 때문에 이 에러가 발생한 것.
그래서 BookServiceImpl.java (@Service) > BookRepo.java (DAO) > book.xml (mapper.xml) 순서대로 경로를 따라가보니 원인을 찾아냈다.
mapper.xml인 book.xml의 query문의 id가 중복된 것을 발견했다.
<select id="select" parameterType="string" resultType="Book">
select * from book
where isbn = #{isbn}
</select>
<!-- 위에서 이미 select id를 사용하므로 아래와 같이 작성하면 이미 매핑되었다는 오류 발생 -->
<select id="select" resultType="Book">
select * from book
</select>
> 해결법 : id가 중복되지 않게 id 속성값을 바꾼다.
나는 아래 query문을 search라는 메소드에서 호출하기 때문에 아래 id값을 search로 바꿔주었다.
그러면 오류가 해결된다.
<참고 사이트>
Cause를 찾는 아이디어를 얻음 : https://stackoverflow.com/questions/37214538/org-springframework-beans-factory-unsatisfieddependencyexception-error-creating