Hello,
I think I have found an error in org.hibernate.cfg.SettingsFactory.buildSettings(Properties props) impelementation. The problem is in folowing code-fragment of SettingsFactory class:
Code:
public Settings buildSettings(Properties props) {
Settings settings = new Settings();
//SessionFactory name:
String sessionFactoryName = props.getProperty(Environment.SESSION_FACTORY_NAME);
settings.setSessionFactoryName(sessionFactoryName);
//JDBC and connection settings:
ConnectionProvider connections = createConnectionProvider(props);
settings.setConnectionProvider(connections);
...
The method „connections.close()“ must be called explicitlly to close all opened connections. Ussually the closing of connections happens in finalize() method but some times finalize() isn’t implemented: for example
C3P0ConnectionProvider.java has no finalize() method.
I used „SHOW PROCESSLIST“ command in MySQL Workbench to observe the growing number of connections during test-execution. After a short time I became an exception in my java program:
Code:
com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"
If I don't use C3P0 pool, the test will be successfully executed!here is my Junit test:
Code:
@Test
public void testManySessionFactories(){
//Number of sets
int numberOfSessionFactories = (int) 1e3;
File configFile = new File(configFileURL);
Configuration cfg = new Configuration().configure(configFile);
cfg.addClass(clazz);
cfg.buildMappings();
PersistentClass map = cfg.getClassMapping(MyBean.class.getCanonicalName() );
Table table = map.getTable();
table.setName(tableName);
String url = dbURL + "/" + dbName;
cfg.setProperty("hibernate.connection.url", url);
cfg.setProperty("hibernate.hbm2ddl.auto", "update");
for(int i=0; i<numberOfSessionFactories; i++){
/**
* failure inside C3P0 implementation this method the ConnectionProvider will be not closed
*/
cfg.buildSettings();
Transaction tx = null;
SessionFactory sessionFactory = null;
Session sess = null;
try {
sessionFactory = cfg.buildSessionFactory();
sess = sessionFactory.openSession(); // open a new Session
tx = sess.beginTransaction();
sess.save(this.randomBeanGenerator.generate());
tx.commit();
} catch (HibernateException ex) {
if (tx!=null) tx.rollback();
throw ex;
} finally {
if(sess!=null)
sess.close();
if(sessionFactory!=null)
sessionFactory.close();
}
}
}