MyBatis - JUnit测试显示'内存不足'

时间:2014-04-14 11:00:51

标签: java spring junit out-of-memory mybatis

我正在使用spring 3.1.1和MyBatis进行JUnit测试。 我创建了一个resultMap并将自定义的typeHandler放到处理null Value。

我的地图如下所示:

<resultMap type="map" id="program">
    <result property="serviceId"        column="ID_SVC"                 typeHandler="StringHandler"/>
    <result property="programId"        column="ID_EVENT"               typeHandler="StringHandler"/>
    <result property="programName"      column="NM_TITLE"               typeHandler="StringHandler"/>
    <result property="directorName"     column="NM_DIRECTOR"            typeHandler="StringHandler"/>
    <result property="actorName"        column="NM_ACT"                 typeHandler="StringHandler"/>
    <result property="ratingCd"         column="CD_RATING"              typeHandler="StringHandler"/>
    <result property="synopsis"         column="NM_SYNOP"               typeHandler="StringHandler"/>
    <result property="img"              column="IMG"                    typeHandler="StringHandler"/>
    <result property="startTime"        column="DT_EVNT_START"/>
    <result property="endTime"          column="DT_EVNT_END"/>
</resultMap>

毫无疑问,我的&#34; StringHandler&#34;工作正常,因为我使用相同处理程序的其他查询无误地工作。

但不知何故,当我执行此查询时,我收到了消息"Out of memory"

DAOTest.testCacheAllProg
testCacheAllProg(com.test.dao.DAOTest)
java.lang.OutOfMemoryError: Java heap space
    at java.util.HashMap.addEntry(HashMap.java:753)
    at java.util.HashMap.put(HashMap.java:385)
    at org.apache.ibatis.type.UnknownTypeHandler.resolveTypeHandler(UnknownTypeHandler.java:93)
    at org.apache.ibatis.type.UnknownTypeHandler.getNullableResult(UnknownTypeHandler.java:51)
    at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:55)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getPropertyMappingValue(DefaultResultSetHandler.java:390)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.applyPropertyMappings(DefaultResultSetHandler.java:364)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getRowValue(DefaultResultSetHandler.java:338)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:291)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:266)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:236)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:150)
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:60)
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:73)
    at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:60)
    at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:267)
    at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:137)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:96)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:77)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:108)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:102)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:358)
    at com.sun.proxy.$Proxy13.selectList(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:198)
    at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:119)
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:63)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52)
    at com.sun.proxy.$Proxy20.getAllProg(Unknown Source)

我不知道为什么会这样。你能从这条消息中找到任何线索吗? 它在iBatis中使用相同的查询和相同的resultMap。(当我在SQLDeveloper中运行此查询时,花了23秒。我知道它有一些问题,但它也可以正常工作)

感谢您帮助我:D

P.S。 对不起,我无法打开我的疑问。它有一些安全问题。

2 个答案:

答案 0 :(得分:0)

看起来MyBatis试图将整个结果集转换为HashMap。还有其他提示,结果集是&#34;相当大&#34;。

我不确定解决方案是什么,但替代方案包括:

  • 增加堆大小(虽然这可能只是推迟了问题),
  • 更改查询以便结果集中的结果更少
  • (某种程度上)改变你的应用程序处理结果的方式,这样它就不需要将它们加载到一个巨大的HashMap中......

答案 1 :(得分:0)

我找到了我需要的东西。 斯蒂芬说,其主要原因是HashMap。 当MyBatis从数据库中提取数据时,它将作为批处理工作。

所以我需要按行和空闲内存来处理。 以下是我为解决这个问题所做的工作。

  • 创建了一个实现的类,它实现了ibatis.ResultHandler。
  • 在mapper界面中为方法添加参数。

例如。

public class RowHandler implements ResultHandler {
  @Override
  public void handleResult(Resultcontext context){
    //I am not sure, but I think I do not have to do anything here.
    //I guess it automatically handle by row by itself.
  }
}  

然后是你的Mapper接口方法:

public Map<String, Object> getProgram(Map<String, Object> param, ResultHandler rowHandler) throws Exception

最后,当您调用该方法时,只需将Customized ResultHandler(在本例中为RowHandler)作为第二个参数。

我完成了我的问题,但了解了MyBatis ResultHandler。如果我错了,你可以在这里添加一些评论。

谢谢!