Spring-Mybatis와 Spring 개발환경에서 여러 DB (multiple DB)를 동시에 사용할 때, ibatis처럼 쓰면 문제가 생길 수 있다. 즉 DB가 꼬이거나 SqlSession instance로 인한 문제가 발생할 수 있다.
(에러 내용) No unique bean of type [org.apache.ibatis.session.SqlSessionFactory] is defined
(결론) org.mybatis.spring.mapper.MapperScannerConfigurer 클래스 대신 org.mybatis.spring.mapper.MapperFactoryBean을 사용해서야 문제가 해결됨
다음과 같은 기본적인 설정을 쓰고 있었다.
<bean id="batch1SqlSession" class="org.mybatis.spring.SqlSessionTemplate" > <constructor-arg index="0" ref="batch2SqlSessionFactory" /> </bean> |
<bean id="xxxxMapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> |
한 개의 DB 사용시는 문제 없는데, 여러 개의 DB 접속시에 문제가 발생할 수 있다.
(원인은 잘못된 API 사용이다.)
즉, org.mybatis.spring.mapper.MapperScannerConfigurer를 사용하는 경우
1) basePackage를 잘못 지정해서 No MyBatis mapper was found in 'xxxx' package. 가 발생한다.
(MapperScannerConfigurer.java:397) No MyBatis mapper was found in 'xxxx' package. Please check your configuration. |
2) Exception 발생
class A1 { @Autowired
class A2 { @Autowired |
SqlSession을 이용하려다가 No unique bean of type 이라는 exception을 만날 수 있다.
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [org.mybatis.spring.SqlSessionTemplate] is defined: expected single matching bean but found 2: [batch1SqlSession, batch2SqlSession]구글 검색하면, Qualifier Annotation 같은 것으로 해결할 수 있다고 하나, 잘못된 API 사용이기 때문에 해결할 수 있다.
3) 엉뚱한 DB로 접근한다.
설정을 어떻게 어떻게 바꿨는데..
A db, B db에 접속했는데, A db에 ‘가’ 쿼리가 날아가기를 기대했는데, B db에 ‘나’쿼리가 접속하여 테이블 없다는 Exception이 발생할 수 있다.
4) 이런 문제를 해결하기 위해서 약간의 공수를 사용해서 문제를 해결할 수 있다.
1)번 예제의 xxxxMapper bean id의 basePackage를 엉뚱한데 두면 해결이 된다.
다만 WARN 에러로그가 남겨진다.
[WARN] No MyBatis mapper was found in ‘XXXX’ package. Please check your configuration. |
소스상 보면, 요행으로 문제가 되는 코드를 피해갈 뿐이었다.
@Override protected Set<BeanDefinitionHolder> doScan(String... basePackages) { Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages); if (beanDefinitions.isEmpty()) { logger.warn("No MyBatis mapper was found in '" + MapperScannerConfigurer.this.basePackage + "' package. Please check your configuration."); } else { … } |
=> 해결
Spring-Mybatis 문서를 참조 (http://code.google.com/p/mybatis/wiki/Spring)해서 다시 코딩하기로 했다.
org.mybatis.spring.mapper.MapperScannerConfigurer 클래스 대신 org.mybatis.spring.mapper.MapperFactoryBean을 사용해서야 문제가 해결되었다.
1) bean 설정
<bean id="googleGatewayDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<bean id="googleGatewaySqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="sqlSessionFactory" ref="googleGatewaySqlSessionFactory" /> |
2) 소스 : mybatis mapper 설정과 연동하는 DAO 코드
public interface GoolgeGatewayDAO { public Template getTemplate(@Param("channelId") String channelId, @Param("language") String language); public String getI18nChannelName(@Param("channelId") String channelId, @Param("language") String language); } |
또는 간결하게 아래 stackoverflow를 통해 쉽게 해결가능하다.
http://stackoverflow.com/questions/4746766/spring-and-mybatis-multiple-data-sources-setup
'general java' 카테고리의 다른 글
File에 String append 하게 도와주는 java code (0) | 2012.10.19 |
---|---|
Spring-Cache 키 생성 유의사항 (0) | 2012.09.05 |
Ehcache와 Spring Cache 사용에 관련한 팁 (1) | 2012.08.29 |
Spring MVC-I18n 지원 (0) | 2012.08.03 |
Spring에서 property의 default value 지정하기 (0) | 2012.08.03 |