在启动大约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();
}
由于
答案 0 :(得分:0)
您获得的实际错误是由测试后存在非常大的数据集引起的。 DatabaseOperation.DELETE.execute(connection, dataSet)
的内部实现可能正在使用诸如DELETE FROM SCENARIO_DESC
之类的SQL语句,并且该表包含太多行以适合内存。
您可以增加内存分配以避免错误。
还有一个查询可能导致内存不足错误。在isTableExist(Connection con)
中,有一个错误的查询来查明表是否存在。它返回表中的所有行。只需将其替换为最多返回0或1行的内容:
SELECT * FROM SCENARIO_DESC LIMIT 1