Tomcat在使用spring-mybatis时启动抛出java.lang.StackOverflowError



Tomcat在使用spring-mybatis时启动抛出java.lang.StackOverflowError。此外,这个错误是随机发生的,非常奇怪。

ERROR org.mybatis.spring.mapper.MapperFactoryBean.checkDaoConfig(MapperFactoryBean.java:97) - Error while adding the mapper 'interface com.myWeb.dao.MyClassMapper' to configuration.
java.lang.StackOverflowError
at java.lang.String.getChars(String.java:783)
at java.lang.String.concat(String.java:1976)
at java.net.URLClassLoader$1.run(URLClassLoader.java:357)
at java.net.URLClassLoader$1.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.access$800(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.access$800(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.access$800(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)

OMG,经过几天的研究,我终于发现了问题。这是因为Mybatis在spring创建mapper实例时启动了多层递归,导致堆栈溢出。我跟踪到SqlSessionDaoSupport(MapperFactoryBean继承它),然后找到这个:

@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。这将持续下去,直到所有的刀都被创造出来。因此,如果你运气不好,它会随意导致最终堆栈溢出错误。

简而言之:这是因为我的mybatis spring版本太低(我使用的是1.1.1版本)。在1.2.0版本中,这种自动连接已从setSqlSessionTemplate和setSqlSessionFactory中删除。

所以:通过将mybatis spring版本更改为高于1.2.0的版本,这个问题得到了解决

相关内容

最新更新