Tomcat start throw java.lang.StackOverflowError when use spring mybatis

Tomcat start throw java.lang.StackOverflowError when use spring mybatis

Tomcat 使用spring mybatis 时开始抛出java.lang.WhosebugError。而且这个错误是随机出现的,很奇怪。

ERROR org.mybatis.spring.mapper.MapperFactoryBean.checkDaoConfig(MapperFactoryBean.java:97) - Error while adding the mapper 'interface com.myWeb.dao.MyClassMapper' to configuration.
java.lang.WhosebugError
    at java.lang.String.getChars(String.java:783)
    at java.lang.String.concat(String.java:1976)
    at java.net.URLClassLoader.run(URLClassLoader.java:357)
    at java.net.URLClassLoader.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:412)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1603)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1533)
    at org.apache.ibatis.scripting.xmltags.XMLScriptBuilder$ForEachHandler.handleNode(XMLScriptBuilder.java:160)
    at org.apache.ibatis.scripting.xmltags.XMLScriptBuilder.parseDynamicTags(XMLScriptBuilder.java:83)
    at org.apache.ibatis.scripting.xmltags.XMLScriptBuilder.access0(XMLScriptBuilder.java:35)
    at org.apache.ibatis.scripting.xmltags.XMLScriptBuilder$IfHandler.handleNode(XMLScriptBuilder.java:167)
    at org.apache.ibatis.scripting.xmltags.XMLScriptBuilder$ChooseHandler.handleWhenOtherwiseNodes(XMLScriptBuilder.java:199)
    at org.apache.ibatis.scripting.xmltags.XMLScriptBuilder$ChooseHandler.handleNode(XMLScriptBuilder.java:187)
    at org.apache.ibatis.scripting.xmltags.XMLScriptBuilder.parseDynamicTags(XMLScriptBuilder.java:83)
    at org.apache.ibatis.scripting.xmltags.XMLScriptBuilder.access0(XMLScriptBuilder.java:35)
    at org.apache.ibatis.scripting.xmltags.XMLScriptBuilder$ForEachHandler.handleNode(XMLScriptBuilder.java:152)
    at org.apache.ibatis.scripting.xmltags.XMLScriptBuilder.parseDynamicTags(XMLScriptBuilder.java:83)
    at org.apache.ibatis.scripting.xmltags.XMLScriptBuilder.access0(XMLScriptBuilder.java:35)
    at org.apache.ibatis.scripting.xmltags.XMLScriptBuilder$TrimHandler.handleNode(XMLScriptBuilder.java:121)
    at org.apache.ibatis.scripting.xmltags.XMLScriptBuilder.parseDynamicTags(XMLScriptBuilder.java:83)

天哪,我研究了几天,终于找到了problem.it的问题,因为Mybatis在spring创建mapper实例的时候会发起多层递归,导致栈溢出。我追踪到 SqlSessionDaoSupport(MapperFactoryBean 继承它)在 org.mybatis.spring.support 中找到这个:

@Autowired(required = false)
public final void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory)   {
   if (!this.externalSqlSession) {
   this.sqlSession = new SqlSessionTemplate(sqlSessionFactory);
   }
}

@Autowired(required = false)
public final void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
   this.sqlSession = sqlSessionTemplate;
   this.externalSqlSession = true;
}

当 MapperFactoryBean 实例被创建时,Spring 将为其注入 SqlSessionTemplate。注入 SqlSessionTemplate 时,它​​将从容器中获取所有 Dao。容器中已经创建了Dao对应的bean就可以捕获了,但是如果bean还没有创建,那么Spring会创建MapperFactoryBean的Dao。当创建 MapperFactoryBean 时,它会再次注入 SqlSessionTemplate。一直这样下去,直到所有的道都被created.So,如果你运气不好,随便造成最后的堆栈溢出错误。

简而言之:是因为我的mybatis-spring版本太低(我用的是1.1.1版本)。并且这种自动装配在 1.2.0 版本的 setSqlSessionTemplate 和 setSqlSessionFactory 中被移除了。

于是:将mybatis-spring版本改成1.2.0以上,问题解决