2013-12-16 27 views
0

当启动约100次junit测试时,我得到了OutOfMemoryError。我怀疑虚拟数据库的访问权限是对这个异常负责。但我没有找到问题的根源。OutOfMemoryError 100次junit测试使用DAO和hsqldb

org.springframework.beans.factory.BeanCreationException:在文件[applicationContext.xml]中定义的名为'sessionFactory'的bean创建时出错:init方法的调用失败;嵌套的例外是java.lang.OutOfMemoryError:java.lang.OutOfMemoryError:由造成Java堆空间 Java堆空间

java.lang.NullPointerException at org.dbunit.operation.AbstractBatchOperation.execute(AbstractBatchOperation.java:125) at myproj.utils.JUnit4DaoTestCase.deleteDataSet(JUnit4DaoTestCase.java:192) at myproj.dao.PrestationEptDAOTest.tearDown(PrestationEptDAOTest.java:48) 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:592) at org.junit.internal.runners.BeforeAndAfterRunner.invokeMethod(BeforeAndAfterRunner.java:74) at org.junit.internal.runners.BeforeAndAfterRunner.runAfters(BeforeAndAfterRunner.java:65) at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:37) at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75) at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45) at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:71)

我怀疑这个类是负责在内存泄漏。这个遗留类被所有的junit测试使用。它在DatabaseOperation.DELETE.execute(connection,dataSet)行失败;

public abstract class JUnit4DaoTestCase extends JUnit4TestCase 
{ 
    private SessionFactory sessionFactory; 

    private Session session; 

    private IDatabaseConnection connection = null; 

    protected static final String schemaName; 

    public static final String DBUNIT_XML_PATH = "metadata/dbunit/"; 

    static 
    { 
     final ResourceBundle db = ResourceBundle.getBundle("database"); 
     schemaName = db.getString("database.schema"); 
    } 

    public void setUp() throws Exception 
    { 
     super.setUp(); 

     // récupération session pour traiter lazy 
     this.sessionFactory = (SessionFactory) ctx.getBean("sessionFactory"); 

     session = SessionFactoryUtils.getSession(this.sessionFactory, true); 
     TransactionSynchronizationManager.bindResource(this.sessionFactory, new SessionHolder(
       session)); 

     if(!isTablesExist(session.connection())) { 
      createTables(session.connection()); 
     } 
     connection = new DatabaseConnection(session.connection(), schemaName); 

    } 

    private boolean isTablesExist(Connection conn) { 
     Statement stmt = null; 
     try { 

      stmt = conn.createStatement(); 
      stmt.execute("SELECT * FROM SCENARIO_DESC"); 
      return true; 

      }catch(SQLException se){ 
       return false; 
      }catch(Exception e){ 
       return false; 
      }finally{ 
       try{ 
       if(stmt!=null) 
        stmt.close(); 
       }catch(SQLException se){ 
       } 
       try{ 
       if(conn!=null) 
        conn.close(); 
       }catch(SQLException se){ 
       se.printStackTrace(); 
       } 
      } 

    } 

    private void createTables(Connection conn) { 
     String fileScriptSql = ""; 
     Statement stmt = null; 
     try { 
      fileScriptSql = FileUtil.convertFileToString("target/Orchestra/WEB-INF/test-classes/createTables_hlsql.sql"); 

      stmt = conn.createStatement(); 
      stmt.execute(fileScriptSql); 
      System.out.println("Created table in given database..."); 

      }catch(SQLException se){ 
       se.printStackTrace(); 
      }catch(Exception e){ 
       e.printStackTrace(); 
      }finally{ 
       try{ 
       if(stmt!=null) 
        stmt.close(); 
       }catch(SQLException se){ 
       } 
       try{ 
       if(conn!=null) 
        conn.close(); 
       }catch(SQLException se){ 
       se.printStackTrace(); 
       } 
      } 
      System.out.println("All tables created in virtual database Hsql!"); 
    } 

    @After 
    public void tearDown() throws Exception 
    { 
     try { 
     TransactionSynchronizationManager.unbindResource(sessionFactory); 
     SessionFactoryUtils.releaseSession(session, sessionFactory); 
     } finally { 
      if(connection!=null) { 
       connection.close(); 
      } 
      if(session!=null) { 
       session.close(); 
      } 
      if(sessionFactory!= null) { 
       sessionFactory.close(); 
      } 

     } 
    } 

    public final void insertDataSet(final IDataSet dataSet) throws HibernateException, SQLException, DatabaseUnitException, FileNotFoundException, IOException 
    { 
     //SessionFactory sessionFactory = (SessionFactory) ctx.getBean("sessionFactory"); 
     //Session session = SessionFactoryUtils.getSession(sessionFactory, true); 



     //connection = new DatabaseConnection(session.connection(), schemaName); 
     try 
     { 
      DatabaseOperation.INSERT.execute(connection, dataSet); 
     } 
     catch (DatabaseUnitException e) 
     { 
      e.printStackTrace(); 
     } 
     catch (SQLException e) 
     { 
      e.printStackTrace(); 
     } 
     finally { 
      if(session != null) { 
       session.close(); 
      } 
     } 
    } 

    public final void deleteDataSet(final IDataSet dataSet) throws HibernateException, DatabaseUnitException 
    { 
     //SessionFactory sessionFactory = (SessionFactory) ctx.getBean("sessionFactory"); 
     //Session session = SessionFactoryUtils.getSession(sessionFactory, true); 
     //IDatabaseConnection connection = null; 
     //connection = new DatabaseConnection(session.connection(), schemaName); 
     try 
     { 
      **DatabaseOperation.DELETE.execute(connection, dataSet);** 
     } 
     catch (DatabaseUnitException e) 
     { 
      e.printStackTrace(); 
     } 
     catch (SQLException e) 
     { 
      e.printStackTrace(); 
     } 
     finally { 
      if(session != null) { 
       session.close(); 
      } 
     } 
    } 

    public final void deleteDataSetByQuery(final String tableName, final String whereCondition, 
      final String pkField) 
    { 
     //IDatabaseConnection connection = null; 

     try 
     { 
      //connection = new DatabaseConnection(session.connection(), schemaName); 
      QueryDataSet partialDataSet; 
      partialDataSet = new QueryDataSet(connection); 
      partialDataSet.addTable(tableName, "select * from " + tableName + " where " 
        + whereCondition); 
      if (partialDataSet.getTable(tableName).getRowCount() > 0) 
      { 
       if (pkField != null && !pkField.equals("")) 
       { 
        // indicate primery 
        DefaultColumnFilter colFilter = new DefaultColumnFilter(); 
        colFilter.includeColumn(pkField); 
        connection.getConfig().setProperty(
          "http://www.dbunit.org/properties/primaryKeyFilter", colFilter); 
       } 
       DatabaseOperation.DELETE.execute(connection, partialDataSet); 
      } 
     } 
     catch (SQLException e) 
     { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     catch (DatabaseUnitException e) 
     { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 

    /** 
    * @param tableName 
    *   String 
    * @param filter 
    *   String 
    * @throws DaoException 
    *    DaoException 
    */ 
    public final void deleteRecordsFromTable(final String tableName, final String filter) 
      throws DaoException 
    { 
     try 
     { 
      String whereCondition = ""; 
      if (filter != null && !filter.equals("")) 
      { 
       whereCondition = " where " + filter; 
      } 
      String hql = "delete from " + tableName + whereCondition; 
      Query query = session.createSQLQuery(hql); 
      query.executeUpdate(); 
     } 
     catch (final DataAccessException e) 
     { 
      throw new DaoException("errorDAO.removeInstance", e); 
     } 
    } 
    /** 
    * @param tabName 
    *   String 
    * @param filter 
    *   String 
    * @return BigDecimal count of the table records 
    */ 
    public final BigDecimal getRecordCount(final String tabName, final String filter) 
    { 
     String whereCondition = ""; 
     if (filter != null && !filter.equals("")) 
     { 
      whereCondition = (" where " + filter); 
     } 
     final Query sqlQuery = session.createSQLQuery("select count(*) from " + tabName 
       + whereCondition); 

     return (BigDecimal) sqlQuery.uniqueResult(); 
    } 

感谢

回答

0

你所得到的实际误差是由测试之后非常大的数据集的存在造成的。 DatabaseOperation.DELETE.execute(connection, dataSet)的内部实现可能使用了诸如DELETE FROM SCENARIO_DESC之类的SQL语句,并且该表的行数太多以适应内存。

您可以增加内存分配以避免错误。

还有一个查询可能会导致内存不足错误。在isTableExist(Connection con)中有一个错误的查询来查找表是否存在。它返回表中的所有行。只需将其替换为最多返回0或1行的东西即可:

SELECT * FROM SCENARIO_DESC LIMIT 1