I have a base class :
Code:
public class BasicPersistentTest extends TestCase {
private final static Logger log = LogManager.getLogger(BasicPersistentTest.class);
protected Session session;
protected Transaction transaction;
// private static SessionFactory sf = getSessionFactory();
protected BusinessContextInfo contextInfo;
protected BusinessContext context;
/**
private static SessionFactory getSessionFactory() {
try {
return new Configuration().configure().buildSessionFactory();
} catch (HibernateException e) {
log.error("ERROR CREATING SESSION FACTORY");
return null;
}
}
**/
public void commit() throws HibernateException {
transaction.commit();
session.close();
try {
HazwebTransactionController.closeSession();
} catch (HazwebFatalException e) {
log.error("PROBLEM CLOSING HIBERNATE SESSION");
throw new HibernateException(e);
}
}
public void begin() throws HibernateException {
// if(sf == null){
// throw new HibernateException("SESSION FACTORY NOT CREATED");
// }
try {
session = HazwebTransactionController.currentSession();
} catch (Exception e) {
log.error("PROBLEM GETTING HIBERNATE SESSION");
throw new HibernateException(e);
}
transaction = session.beginTransaction();
}
}
That my tests inherit from. Initially i didn't bother using the ThreadLocal pettern because the tests were running consecutively so there was no threading issues. Originally the session variable in begin() was set:
Code:
session=sf.getSession().
I added the use of ThreadLocal as a debugging technique.
A typical test that would inherit from this class would be:
Code:
public void testGetGenerator() throws HibernateException, HazwebFatalException, BadPersistentIdException {
log.debug("testGetChemWasteRoom()");
try {
begin();
generatorManager = BeanLookup.getGeneratorManager(contextInfo);
generatorDescription = "genDesc";
contactPerson = "contact";
phoneNumber = "phoneNumber";
email = "email";
department = "department";
shippingAddress = "shippingAddress";
comments = "comments";
Generator generatorPers = new Generator(generatorDescription, contactPerson, phoneNumber, email, department, shippingAddress, comments);
session.save(generatorPers);
commit();
GeneratorManager genManager = BeanLookup.getGeneratorManager(contextInfo);
long generatorId = generatorPers.getId().longValue();
ShortGeneratorInfo generatorInfo = genManager.getGenerator(generatorId, contextInfo);
assertEquals("Bad id", generatorPers.getId().toString(), generatorInfo.getId());
assertEquals("Bad last updated", generatorPers.getLastUpdated(), generatorInfo.getLastUpdated());
assertEquals("Bad description", generatorDescription, generatorInfo.getGeneratorDescription());
assertEquals("Bad contactPerson", contactPerson, generatorInfo.getContactPerson());
assertEquals("Bad phoneNumber", phoneNumber, generatorInfo.getPhoneNumber());
assertEquals("Bad email", email, generatorInfo.getEmail());
assertEquals("Bad department", department, generatorInfo.getDepartment());
assertEquals("Bad shippingAddress", shippingAddress, generatorInfo.getShippingAddress());
assertEquals("Bad comments", comments, generatorInfo.getComments());
} finally {
if (transaction != null) {
try {
transaction.rollback();
} catch (HibernateException e1) {
log.error("ERROR ROLLING BACK IN TEST");
}
}
}
log.debug("TEST OK");
}
The code for generatorManager is:
Code:
/**
* Retrieve a Generator
*
* @param generatorId
* @param contextInfo
* @return {@link GeneratorInfo} representing the generator with id generatorId
* @throws HazwebFatalException
*/
public ShortGeneratorInfo getGenerator(long generatorId, BusinessContextInfo contextInfo)
throws HazwebFatalException, BadPersistentIdException {
//@todo add security checks
dataAccessLog.info("GeneratorManagerImpl.getGenerator ==>");
Transaction tx = null;
try {
Session session = HazwebTransactionController.currentSession();
tx = session.beginTransaction();
IGeneratorManagerHelper genManHelper = ManagerHelperFactory.getGeneratorManager(HazWebDataUtil.createBusinessContext(contextInfo),
session);
ShortGeneratorInfo generatorInfo = genManHelper.getGenerator(generatorId);
tx.commit();
return generatorInfo;
} catch (BadPersistentIdException bpid) {
log.error("Entity of type " + bpid.getEntityType() + " with id " + bpid.getBadId() + " does not exist");
rollback(tx, log);
throw bpid;
} catch (Exception e) {
log.error("Unexpected exception in business call", e);
if (tx != null) {
try {
tx.rollback();
} catch (HibernateException e1) {
log.error("Failure to rollback transaction", e1);
}
}
throw new HazwebFatalException("Unexpected exception in business call");
} finally {
dataAccessLog.info("GeneratorManagerImpl.getGenerator <==");
HazwebTransactionController.closeSession();
}
}
The code for the helper class is:
Code:
public ShortGeneratorInfo getGenerator(long generatorId) throws BadPersistentIdException {
log.debug("getGenerator()");
Generator genPers = (Generator) PersistenceHelper.findPersistentObject(generatorId, Generator.class, getSession());
return generatorConvertor.persToShortInfo(genPers);
}
As far as i can see, this test should only ever need one connection at a time. The manager calls handle there own transactions and the setup code is called within a begin()-commit() either before or after.
For testing, i don't use any connection pooling, just the one that hibernate provides. Here's my hibernate.properties:
Code:
######################
### Query Language ###
######################
## define query language constants / function names
hibernate.query.substitutions true 1, false 0, yes 'Y', no 'N'
#DYNAMIC
hibernate.dialect @HibernateDialect@
hibernate.connection.driver_class @DatabaseDriver@
hibernate.connection.url @DatabaseUrl@
hibernate.connection.username @DatabaseUserName@
hibernate.connection.password @DatabasePassword@
#################
### Platforms ###
#################
## JNDI Datasource
#hibernate.connection.datasource jdbc/test
#hibernate.connection.username db2
#hibernate.connection.password db2
## HypersonicSQL
#hibernate.dialect net.sf.hibernate.dialect.HSQLDialect
#hibernate.connection.driver_class org.hsqldb.jdbcDriver
#hibernate.connection.username sa
#hibernate.connection.password
#hibernate.connection.url jdbc:hsqldb:hsql://localhost
#hibernate.connection.url jdbc:hsqldb:test
#hibernate.connection.url jdbc:hsqldb:.
## PostgreSQL
#hibernate.dialect net.sf.hibernate.dialect.PostgreSQLDialect
#hibernate.connection.driver_class org.postgresql.Driver
#hibernate.connection.url jdbc:postgresql:template1
#hibernate.connection.username pg
#hibernate.connection.password
#hibernate.query.substitutions yes 'Y', no 'N'
## DB2
#hibernate.dialect net.sf.hibernate.dialect.DB2Dialect
#hibernate.connection.driver_class COM.ibm.db2.jdbc.app.DB2Driver
#hibernate.connection.url jdbc:db2:test
#hibernate.connection.username db2
#hibernate.connection.password db2
## DB2/400
#hibernate.dialect net.sf.hibernate.dialect.DB2400Dialect
#hibernate.connection.username user
#hibernate.connection.password password
## Native driver
#hibernate.connection.driver_class COM.ibm.db2.jdbc.app.DB2Driver
#hibernate.connection.url jdbc:db2://systemname
## Toolbox driver
#hibernate.connection.driver_class com.ibm.as400.access.AS400JDBCDriver
#hibernate.connection.url jdbc:as400://systemname
## MySQL
#hibernate.dialect net.sf.hibernate.dialect.MySQLDialect
#hibernate.connection.driver_class org.gjt.mm.mysql.Driver
#hibernate.connection.driver_class com.mysql.jdbc.Driver
#hibernate.connection.url jdbc:mysql:///hazmat
#hibernate.connection.username hazmatDevel
#hibernate.connection.password Resaklop@
## Oracle
#hibernate.dialect net.sf.hibernate.dialect.Oracle9Dialect
#hibernate.dialect net.sf.hibernate.dialect.OracleDialect
#hibernate.connection.driver_class oracle.jdbc.driver.OracleDriver
#hibernate.connection.username ora
#hibernate.connection.password ora
#hibernate.connection.url jdbc:oracle:thin:@localhost:1521:test
## Sybase
#hibernate.dialect net.sf.hibernate.dialect.SybaseDialect
#hibernate.connection.driver_class com.sybase.jdbc2.jdbc.SybDriver
#hibernate.connection.username sa
#hibernate.connection.password sasasa
#hibernate.connection.rl jdbc:sybase:Tds:co3061835-a:5000/tempdb
## Mckoi SQL
#hibernate.dialect net.sf.hibernate.dialect.MckoiDialect
#hibernate.connection.driver_class com.mckoi.JDBCDriver
#hibernate.connection.url jdbc:mckoi:///
#hibernate.connection.url jdbc:mckoi:local://C:/mckoi1.00/db.conf
#hibernate.connection.username admin
#hibernate.connection.password nimda
## SAP DB
#hibernate.dialect net.sf.hibernate.dialect.SAPDBDialect
#hibernate.connection.driver_class com.sap.dbtech.jdbc.DriverSapDB
#hibernate.connection.url jdbc:sapdb://localhost/TST
#hibernate.connection.username TEST
#hibernate.connection.password TEST
#hibernate.query.substitutions yes 'Y', no 'N'
## MS SQL Server
#hibernate.dialect net.sf.hibernate.dialect.SQLServerDialect
#hibernate.connection.username sa
#hibernate.connection.password sa
## JSQL Driver
#hibernate.connection.driver_class com.jnetdirect.jsql.JSQLDriver
#hibernate.connection.url jdbc:JSQLConnect://1E1/test
## JTURBO Driver
#hibernate.connection.driver_class com.newatlanta.jturbo.driver.Driver
#hibernate.connection.url jdbc:JTurbo://1E1:1433/test
## WebLogic Driver
#hibernate.connection.driver_class weblogic.jdbc.mssqlserver4.Driver
#hibernate.connection.url jdbc:weblogic:mssqlserver4:1E1:1433
## Microsoft Driver (not recommended!)
#hibernate.connection.driver_class com.microsoft.jdbc.sqlserver.SQLServerDriver
#hibernate.connection.url jdbc:microsoft:sqlserver://1E1;DatabaseName=test;SelectMethod=cursor
## jTDS (not supported!)
#hibernate.connection.driver_class net.sourceforge.jtds.jdbc.Driver
#hibernate.connection.url jdbc:jtds:sqlserver://1E1/test;SelectMethod=cursor
#hibernate.jdbc.use_scrollable_resultset false
## Interbase
#hibernate.dialect net.sf.hibernate.dialect.InterbaseDialect
#hibernate.connection.username sysdba
#hibernate.connection.password masterkey
## DO NOT specify hibernate.connection.sqlDialect
## InterClient
#hibernate.connection.driver_class interbase.interclient.Driver
#hibernate.connection.url jdbc:interbase://localhost:3060/C:/firebird/test.gdb
## Pure Java
#hibernate.connection.driver_class org.firebirdsql.jdbc.FBDriver
#hibernate.connection.url jdbc:firebirdsql:localhost/3050:/firebird/test.gdb
## Pointbase
#hibernate.dialect net.sf.hibernate.dialect.PointbaseDialect
#hibernate.connection.driver_class com.pointbase.jdbc.jdbcUniversalDriver
#hibernate.connection.url jdbc:pointbase:embedded:sample
#hibernate.connection.username PBPUBLIC
#hibernate.connection.password PBPUBLIC
#################################
### Hibernate Connection Pool ###
#################################
hibernate.connection.pool_size 1
###########################
### C3P0 Connection Pool###
###########################
#hibernate.c3p0.max_size 2
#hibernate.c3p0.min_size 2
#hibernate.c3p0.timeout 5000
#hibernate.c3p0.max_statements 100
#hibernate.c3p0.idle_test_period 3000
#hibernate.c3p0.acquire_increment 2
##hibernate.c3p0.validate false
###################################
### Apache DBCP Connection Pool ###
###################################
## connection pool
#hibernate.dbcp.maxActive 100
#hibernate.dbcp.whenExhaustedAction 1
#hibernate.dbcp.maxWait 120000
#hibernate.dbcp.maxIdle 10
## prepared statement cache
#hibernate.dbcp.ps.maxActive 100
#hibernate.dbcp.ps.whenExhaustedAction 1
#hibernate.dbcp.ps.maxWait 120000
#hibernate.dbcp.ps.maxIdle 10
## optional query to validate pooled connections:
#hibernate.dbcp.validationQuery select 1 from dual
#hibernate.dbcp.testOnBorrow true
#hibernate.dbcp.testOnReturn false
##############################
### Proxool Connection Pool###
##############################
## Properties for external configuration of Proxool
hibernate.proxool.pool_alias pool1
## Only need one of the following
#hibernate.proxool.existing_pool true
#hibernate.proxool.xml proxool.xml
#hibernate.proxool.properties proxool.properties
## Or, alternatively, all of these
## Standard configuration properties of Proxool
#hibernate.proxool.house-keeping-sleep-time 30000
#hibernate.proxool.house-keeping-test-sql
#hibernate.proxool.maximum-connection-count 4
#hibernate.proxool.maximum-connection-lifetime 4
#hibernate.proxool.simultaneous-build-throttle 2
#hibernate.proxool.maximum-active-time 500
#hibernate.proxool.minimum-connection-count 2
#hibernate.proxool.fatal-sql-exception
#hibernate.proxool.prototype-count
#hibernate.proxool.statistics
#hibernate.proxool.recently-started-threshold
#hibernate.proxool.overload-without-refusal-lifetime
#################################
### Plugin ConnectionProvider ###
#################################
## use a custom ConnectionProvider (if not set, Hibernate will choose a built-in ConnectionProvider using hueristics)
#hibernate.connection.provider_class net.sf.hibernate.connection.DriverManagerConnectionProvider
#hibernate.connection.provider_class net.sf.hibernate.connection.DatasourceConnectionProvider
#hibernate.connection.provider_class net.sf.hibernate.connection.C3P0ConnectionProvider
#hibernate.connection.provider_class net.sf.hibernate.connection.DBCPConnectionProvider
#hibernate.connection.provider_class net.sf.hibernate.connection.ProxoolConnectionProvider
#######################
### Transaction API ###
#######################
## the Transaction API abstracts application code from the underlying JTA or JDBC transactions
#hibernate.transaction.factory_class net.sf.hibernate.transaction.JTATransactionFactory
#hibernate.transaction.factory_class net.sf.hibernate.transaction.JDBCTransactionFactory
## to use JTATransactionFactory, Hibernate must be able to locate the UserTransaction in JNDI
## default is java:comp/UserTransaction
## you do NOT need this setting if you specify hibernate.transaction.manager_lookup_class
#jta.UserTransaction jta/usertransaction
#jta.UserTransaction javax.transaction.UserTransaction
#jta.UserTransaction UserTransaction
## to use JCS caching with JTA, Hibernate must be able to obtain the JTA TransactionManager
#hibernate.transaction.manager_lookup_class net.sf.hibernate.transaction.JBossTransactionManagerLookup
#hibernate.transaction.manager_lookup_class net.sf.hibernate.transaction.WeblogicTransactionManagerLookup
#hibernate.transaction.manager_lookup_class net.sf.hibernate.transaction.WebSphereTransactionManagerLookup
#hibernate.transaction.manager_lookup_class net.sf.hibernate.transaction.OrionTransactionManagerLookup
#hibernate.transaction.manager_lookup_class net.sf.hibernate.transaction.ResinTransactionManagerLookup
##############################
### Miscellaneous Settings ###
##############################
## print all generated SQL to the console
hibernate.show_sql true
## auto schema export
#hibernate.hbm2ddl.auto create-drop
#hibernate.hbm2ddl.auto create
#hibernate.hbm2ddl.auto update
## specify a JDBC isolation level
#hibernate.connection.isolation 4
## set the JDBC fetch size
#hibernate.jdbc.fetch_size 25
## set the maximum JDBC 2 batch size (a nonzero value enables batching)
hibernate.jdbc.batch_size 0
## enable use of JDBC 2 scrollable ResultSets (specifying a Dialect will cause Hibernate to use a sensible default)
#hibernate.jdbc.use_scrollable_resultset true
## use streams when writing binary types to / from JDBC
hibernate.jdbc.use_streams_for_binary true
## use JDBC 3 PreparedStatement.getGeneratedKeys to get the identifier of an inserted row
#hibernate.jdbc.use_get_generated_keys true
## specify a default schema for unqualified tablenames
#hibernate.default_schema test
## use a custom stylesheet for XML generation (if not specified, hibernate-default.xslt will be used)
#hibernate.xml.output_stylesheet C:/Hibernate/net/sf/hibernate/hibernate-default.xslt
## enable outerjoin fetching (specifying a Dialect will cause Hibernate to use sensible default)
#hibernate.use_outer_join false
## set the maximum depth of the outer join fetch tree
hibernate.max_fetch_depth 1
## enable CGLIB reflection optimizer (enabled by default)
#hibernate.cglib.use_reflection_optimizer false
##########################
### Second-level Cache ###
##########################
## optimize chache for minimal "puts" instead of minimal "gets" (good for clustered cache)
#hibernate.cache.use_minimal_puts true
## enable the query cache
hibernate.cache.use_query_cache true
## choose a cache implementation
#hibernate.cache.provider_class net.sf.ehcache.hibernate.Provider
#hibernate.cache.provider_class net.sf.hibernate.cache.EmptyCacheProvider
hibernate.cache.provider_class net.sf.hibernate.cache.HashtableCacheProvider
#hibernate.cache.provider_class net.sf.hibernate.cache.TreeCacheProvider
#hibernate.cache.provider_class net.sf.hibernate.cache.OSCacheProvider
#hibernate.cache.provider_class net.sf.hibernate.cache.JCSCacheProvider
#hibernate.cache.provider_class net.sf.hibernate.cache.SwarmCacheProvider
############
### JNDI ###
############
## specify a JNDI name for the SessionFactory
#hibernate.session_factory_name hibernate/session_factory
## Hibernate uses JNDI to bind a name to a SessionFactory and to look up the JTA UserTransaction;
## if hibernate.jndi.* are not specified, Hibernate will use the default InitialContext() which
## is the best approach in an application server
#file system
#hibernate.jndi.class com.sun.jndi.fscontext.RefFSContextFactory
#hibernate.jndi.url file:/
#WebSphere
#hibernate.jndi.class com.ibm.websphere.naming.WsnInitialContextFactory
#hibernate.jndi.url iiop://localhost:900/
I tried upping the hibernate.connection.pool_size to 5 or 100 but it didn't help, though i don't think this should be necessary for unit tests anyway.
Do you see something i'm missing?
M@[/quote]