Java 使用DAO和hsqldb进行100次junit测试后发生OutOfMemoryError
我在启动大约100个junit测试时遇到了OutOfMemoryError。我怀疑对虚拟数据库的访问应该对此异常负责。但我没能找到问题的根源 org.springframework.beans.factory.BeanCreationException:创建名为[applicationContext.xml]中定义的“sessionFactory”的bean时出错:调用init方法失败;嵌套异常为java.lang.OutOfMemoryError:java堆空间 原因:java.lang.OutOfMemoryError:java堆空间 位于的java.lang.NullPointerException org.dbunit.operation.AbstractBatchOperation.executeAbstractBatchOperation.java:125 在 myproj.utils.JUnit4DaoTestCase.deleteDataSetJUnit4DaoTestCase.java:192 在 java:48 在sun.reflect.NativeMethodAccessorImpl.invoke0Native方法在 sun.reflect.NativeMethodAccessorImpl.invokeNativeMethodAccessorImpl.java:39 在 sun.reflect.DelegatingMethodAccessorImpl.invokeDelegatingMethodAccessorImpl.java:25 java:592 at org.junit.internal.runners.beforeandferrunner.invokeMethodBeforeAndAfterRunner.java:74 在 java:65 在 org.junit.internal.runners.beforeandferrunner.runprotectedbeforeandferrunner.java:37 在 org.junit.internal.runners.TestMethodRunner.runMethodTestRunner.java:75 在 org.junit.internal.runners.TestMethodRunner.runTestMethodRunner.java:45 在 org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethodTestClassMethodsRunner.java:71 我怀疑这个类应该对内存中的泄漏负责。所有junit测试都使用这个遗留类。在DatabaseOperation.DELETE.executeconnection,dataSet行失败Java 使用DAO和hsqldb进行100次junit测试后发生OutOfMemoryError,java,junit,hsqldb,Java,Junit,Hsqldb,我在启动大约100个junit测试时遇到了OutOfMemoryError。我怀疑对虚拟数据库的访问应该对此异常负责。但我没能找到问题的根源 org.springframework.beans.factory.BeanCreationException:创建名为[applicationContext.xml]中定义的“sessionFactory”的bean时出错:调用init方法失败;嵌套异常为java.lang.OutOfMemoryError:java堆空间 原因:java.lang.Ou
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();
}
谢谢您得到的实际错误是由于测试后存在非常大的数据集造成的。DatabaseOperation.DELETE.executeconnection的内部实现,dataSet可能正在使用SQL语句,如DELETE FROM SCENARIO_DESC,表中的行太多,无法放入内存 您可以增加内存分配以避免错误 还有一个查询可能导致内存不足错误。在isTableExistConnection con中,有一个错误的查询用于查找表是否存在。它返回表中的所有行。只需将其替换为最多返回0或1行的类似内容:
SELECT * FROM SCENARIO_DESC LIMIT 1