2013-12-16 28 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