OutOfMemoryError使用DAO和hsqldb进行100次junit测试

时间:2013-12-16 16:41:12

标签: java junit hsqldb

在启动大约100次junit测试时,我得到了OutOfMemoryError。我怀疑对虚拟数据库的访问是否对此异常负责。但我没有找到问题根源的运气。

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

  

java.lang.NullPointerException at   org.dbunit.operation.AbstractBatchOperation.execute(AbstractBatchOperation.java:125)     在   myproj.utils.JUnit4DaoTestCase.deleteDataSet(JUnit4DaoTestCase.java:192)     在   myproj.dao.PrestationEptDAOTest.tearDown(PrestationEptDAOTest.java:48)     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at   sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)     在   sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)     在java.lang.reflect.Method.invoke(Method.java:592)at   org.junit.internal.runners.BeforeAndAfterRunner.invokeMethod(BeforeAndAfterRunner.java:74)     在   org.junit.internal.runners.BeforeAndAfterRunner.runAfters(BeforeAndAfterRunner.java:65)     在   org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:37)     在   org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75)     在   org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45)     在   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();
    }

由于

1 个答案:

答案 0 :(得分:0)

您获得的实际错误是由测试后存在非常大的数据集引起的。 DatabaseOperation.DELETE.execute(connection, dataSet)的内部实现可能正在使用诸如DELETE FROM SCENARIO_DESC之类的SQL语句,并且该表包含太多行以适合内存。

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

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

SELECT * FROM SCENARIO_DESC LIMIT 1