有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java MyBatis JUnit测试显示“内存不足”

我正在用spring 3.1.1和MyBatis进行JUnit测试。 我制作了一个resultMap并放置了一个定制的typeHandler来处理空值

我的地图如下所示:

<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>

毫无疑问,我的“StringHandler”工作得很好,因为我的其他查询使用同一个处理程序时不会出错

但不知何故,当我做这个查询时,我得到了一条消息^{

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中使用相同的查询和相同的结果映射。(当我在SQLDeveloper中运行这个查询时,花了23秒。我知道它有一些问题,但至少可以正常工作)

谢谢你帮我:D

附言。 很抱歉,我无法打开我的查询。它有一些安全问题


共 (2) 个答案

  1. # 1 楼答案

    看起来MyBatis正在尝试将整个结果集转换为HashMap。还有其他迹象表明,结果集“相当大”

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

    • 增加堆大小(尽管这可能只是推迟问题的发生)
    • 更改查询以便结果集中的结果更少
    • (以某种方式)更改应用程序处理结果的方式,这样就不需要将结果加载到一个巨大的HashMap中
  2. # 2 楼答案

    我找到了我需要的东西。 正如Stephen所说,其主要原因是HashMap。 当MyBatis从数据库中提取数据时,它会以批处理的方式工作

    所以我需要按行处理并释放内存。 以下是我为解决这个问题所做的

    • 创建了一个实现ibatis的实现类。结果是德勒
    • 在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.
      }
    }  
    

    然后,映射器接口方法:

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

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

    我已经解决了我的问题,但对MyBatis的了解却带来了麻烦。如果我错了,你可以在下面加上一些评论

    谢谢