ok, an update... i'm getting to grips with jProfiler a bit more now and think that it's the iBatis static SqlMap instances that i'm creating in my EJBs that are not freeing up resources. I'm setting them to NULL after i've used them but they are still not getting cleaned up.
This is the code from one of my Stateless Session Beans, and i've also included the code from the SqlMapConfig class that returns the sqlMap instance... i have edited the standard one to return a specific one for each type of dB access.
<ejb code>
public List getAnnoucements(Date todaysDate) throws SQLException
{
// Get configured SqlMap instance
SqlMap sqlMap = SqlMapConfig.getSqlMap(Constants.APP_READ);
try
{
// Execute the query
List results = sqlMap.executeQueryForList("selectXXX", todaysDate);
sqlMap = null;
return results;
}
catch (Exception e)
{
// throw as SQL exception
throw (SQLException)e.fillInStackTrace();
}
}
</ejb code>
<SqlMapConfig code>
public class SqlMapConfig
{
// Get instance of Log4j logger
static Logger logger = Logger.getLogger(SqlMapConfig.class);
// -- SqlMap instances are
thread safe.
protected static final SqlMap sqlMap_appRead;
protected static final SqlMap sqlMap_appWrite;
protected static final SqlMap sqlMap_loginRead;
protected static final SqlMap sqlMap_loginWrite;
static
{
try
{
if(logger.isDebugEnabled()) logger.debug("SqlMapConfig called");
// -- Load the SQL Map configuration XML file a Reader or a File, referenced from the classes directory.
// -- The iBATIS common library includes a handy Resources utility class perfect for this.
// -- You can disable XML validation, it is enabled by default.
// XmlSqlMapBuilder.setValidationEnabled(false);
// Use the XmlSqlMapBuilder to build the SQL Maps from the reader.
sqlMap_appRead = XmlSqlMapBuilder.buildSqlMap(Resources.getResourceAsReader("sqlmaps/SqlMapConfig_appRead.xml"));
sqlMap_appWrite = XmlSqlMapBuilder.buildSqlMap(Resources.getResourceAsReader("sqlmaps/SqlMapConfig_appWrite.xml"));
sqlMap_loginRead = XmlSqlMapBuilder.buildSqlMap(Resources.getResourceAsReader("sqlmaps/SqlMapConfig_loginRead.xml"));
sqlMap_loginWrite = XmlSqlMapBuilder.buildSqlMap(Resources.getResourceAsReader("sqlmaps/SqlMapConfig_loginWrite.xml"));
if(logger.isDebugEnabled()) logger.debug("SqlMaps built ok!");
}
catch (Exception e)
{
// If we fail here we just want to fail gracefully.
// Errors at this point will be unrecoverable and we
// want to know about them at system startup time,
// not after hours of operation.
throw new NestedRuntimeException("Error initializing SqlMap. Cause: " + e, e);
}
}
/**
* Gets a SqlMap object based on the requested mapType
* @param mapType
* @return SqlMap object
*/
public static SqlMap getSqlMap(
String mapType)
{
// Return the specific SqlMap type, appRead is returned by default.
if (Constants.APP_WRITE.equalsIgnoreCase(mapType))
{
if(logger.isDebugEnabled()) logger.debug("app_write sqlMap returned");
return sqlMap_appWrite;
}
else if (Constants.LOGIN_READ.equalsIgnoreCase(mapType))
{
if(logger.isDebugEnabled()) logger.debug("login_read sqlMap returned");
return sqlMap_loginRead;
}
else if (Constants.LOGIN_WRITE.equalsIgnoreCase(mapType))
{
if(logger.isDebugEnabled()) logger.debug("login_write sqlMap returned");
return sqlMap_loginWrite;
}
if(logger.isDebugEnabled()) logger.debug("app_read sqlMap returned");
return sqlMap_appRead;
}
}
</SqlMapConfig code>
Sorry for the long post, but i thought the more info the better. Thanks in advance, Ed.