Hi, I have written a JUnit test that uses the spring framework to create a few session factories (each connecting to a different database)
and providing some DAO (DBCache) so that I can test the functionality of my DAO in one JUnit test against a list of databases.
The spring configuration looks like
Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<!-- ================================================================================ -->
<!-- autosense map for connection pools -->
<!-- ================================================================================ -->
<bean id="system.jdbc.autosensemap" class="java.util.LinkedHashMap">
<constructor-arg>
<map>
<entry key="(?i).*db2/nt.*" value="DB2,org.hibernate.dialect.DB2Dialect" />
<entry key="(?i).*db2.*" value="DB2v7_Host,org.hibernate.dialect.DB2Dialect" />
<entry key="(?i).*microsoft sql server.*" value="mssql,org.hibernate.dialect.SQLServerDialect" />
<entry key="(?i).*oracle.*10.*" value="oracle,org.hibernate.dialect.Oracle10gDialect" />
<entry key="(?i).*oracle.*9.*" value="oracle,org.hibernate.dialect.Oracle9Dialect" />
<entry key="(?i).*oracle.*" value="oracle,org.hibernate.dialect.Oracle10gDialect" />
<entry key="(?i).*mysql.*version:\s*5\..*" value="mysql,org.hibernate.dialect.MySQL5Dialect" />
<entry key="(?i).*mysql.*" value="mysql,org.hibernate.dialect.MySQLDialect" />
<entry key="(?i).*derby.*" value="derby,org.hibernate.dialect.DerbyDialect" />
<entry key="(?i)hsql.*" value="hsql,org.hibernate.dialect.HSQLDialect" />
</map>
</constructor-arg>
</bean>
<!-- ================================================================================ -->
<!-- connection pools -->
<!-- ================================================================================ -->
<bean id="abstract-connection-pool" class="biz.i2z.container.connectionpool.impl.ConnectionPoolJDBC" abstract="true">
<property name="host" value="localhost" />
<property name="user" value="csp" />
<property name="password" value="operating" />
<property name="database" value="csp_demo" />
<property name="poolSize" value="10" />
<property name="checkValidConnectionSql" value="SELECT TESTCOL FROM TESTCON" />
<property name="sqlVariant" value="autosense" />
<property name="hibernateDialectClass" value="autosense" />
<property name="connectionLifetime" value="300000" />
<property name="checkInterval" value="60000" />
<property name="maxPoolSize" value="-1" />
<property name="dialectAutoSenseMap" ref="system.jdbc.autosensemap" />
<property name="verbose" value="true" />
</bean>
<bean id="connection-pool.mssql" parent="abstract-connection-pool">
<property name="connectionURL" value="jdbc:sqlserver://localhost:1433;databaseName=csp_demo;sendStringParametersAsUnicode=false" />
<property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
<property name="checkValidConnectionSql" value="SELECT 1" />
<!--<property name="hibernateDialectClass" value="org.hibernate.dialect.SQLServerDialect" />-->
</bean>
<bean id="connection-pool.mysql" parent="abstract-connection-pool">
<property name="connectionURL" value="jdbc:mysql://localhost:3306/csp_demo?autoReconnect=true" />
<property name="driver" value="com.mysql.jdbc.Driver" />
</bean>
<bean id="connection-pool.derby" parent="abstract-connection-pool">
<property name="connectionURL" value="jdbc:derby:res-junit/db;user=csp;password=operating;create=true" />
<property name="driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="checkValidConnectionSql" value="select * from SYSIBM.SYSDUMMY1" />
</bean>
<!-- ================================================================================ -->
<!-- session factories -->
<!-- ================================================================================ -->
<bean id="abstract-sessionFactory" class="biz.i2z.ioc.HibernateSessionFactoryBean" abstract="true">
<property name="connectionPool" value="CP1" />
<property name="hbm2DdlAuto" value="update" />
<property name="cacheProviderClass" value="net.sf.ehcache.hibernate.EhCacheProvider" />
<property name="useQueryCache" value="true" />
<property name="useSecondLevelCache" value="true" />
<property name="showSql" value="false" />
<property name="configurationResourceName" value="res-junit/cache/ehcache-junit.xml" />
<property name="mappingLocations">
<list>
<value>res-junit/cache/CacheEntry.hbm.xml</value>
</list>
</property>
</bean>
<bean id="sessionFactory.mssql" parent="abstract-sessionFactory">
<property name="connectionPool" ref="connection-pool.mssql" />
<property name="configurationResourceName" value="res-junit/cache/ehcache-junit.xml" />
</bean>
<bean id="sessionFactory.mysql" parent="abstract-sessionFactory">
<property name="connectionPool" ref="connection-pool.mysql" />
<property name="configurationResourceName" value="res-junit/cache/ehcache-junit.xml" />
</bean>
<bean id="sessionFactory.derby" parent="abstract-sessionFactory">
<property name="connectionPool" ref="connection-pool.derby" />
<property name="configurationResourceName" value="res-junit/cache/ehcache-junit.xml" />
</bean>
<!-- ================================================================================ -->
<!-- caches -->
<!-- ================================================================================ -->
<bean id="abstract-dbcache" class="biz.i2z.system.distributed.impl.DBCache" abstract="true">
<property name="maxDBTTL" value="-1" />
<property name="ttlCheckInterval" value="3600000" />
<property name="maxTimeForKeysGet" value="10000" />
<property name="domainTTL">
<map>
<!--<entry key="SharedSessionManager/Session" value="-1" />-->
</map>
</property>
</bean>
<bean id="dbcache.mssql" parent="abstract-dbcache">
<property name="sessionFactory" ref="sessionFactory.mssql" />
</bean>
<bean id="dbcache.mysql" parent="abstract-dbcache">
<property name="sessionFactory" ref="sessionFactory.mysql" />
</bean>
<bean id="dbcache.derby" parent="abstract-dbcache">
<property name="sessionFactory" ref="sessionFactory.derby" />
</bean>
<bean id="dbcache.default" parent="dbcache.derby">
</bean>
<util:list id="dbcaches">
<ref bean="dbcache.mssql"/>
<ref bean="dbcache.mysql"/>
<ref bean="dbcache.derby"/>
<ref bean="dbcache.mysql"/>
<ref bean="dbcache.oracle"/>
<ref bean="dbcache.db2"/>
</util:list>
</beans>
so that you can have a look at what I am doing.
The problem I am facing is that - when running a test on all session factories - entities don't get written
in the database even though hibernate (showSql=true) says that it inserts the entities (I have INSERT INTO logs
on the console).
Especially this test fails:
Code:
@Test
public void testCacheIterativelyForAllDBs() {
int nCountEntries = 400;
try {
List<DBCache> cs = this.getCaches("dbcaches");
for (DBCache cache : cs) {
for (Map.Entry<String, FileContentCacheEntry> resourceEntry : resources.entrySet()) {
FileContentCacheEntry resource = resourceEntry.getValue();
this.processIteratively(cache, resource, nCountEntries);
}
}
} catch (Exception e) {
failWith(String.format("error running iterative test: %s", e.getMessage()), e);
}
}
private Map<String, Double> processIteratively(DBCache cache, FileContentCacheEntry resource, int nCountEntries) {
/*
* prepare a domain
*/
String domain = String.format("D%d", System.currentTimeMillis());
Map<String, Double> statistics = new TreeMap<String, Double>();
try {
/*
* write entries
*/
Set<String> keys = new HashSet<String>();
long duration = 0;
for (int i=0; i < nCountEntries; i++) {
String key = String.format("c%sr%st%di%d", cache.getId(), resource.getFilename(), System.currentTimeMillis(), i);
keys.add(key);
long t1 = System.currentTimeMillis();
this.cache.put(domain, key, resource);
duration += (System.currentTimeMillis() - t1);
}
statistics.put("avgDurationSerialWrite", new Double(duration / nCountEntries));
/*
* read back entries
*/
duration = 0;
for (String key : keys) {
long t1 = System.currentTimeMillis();
cache.get(domain, key);
duration += (System.currentTimeMillis() - t1);
}
statistics.put("avgDurationSerialRead", new Double(duration / nCountEntries));
/*
* check if all the entries are present in the cache
*/
Set<Object> os = cache.getKeys(domain);
Assert.assertNotNull("cache does not contain entries", os);
Assert.assertEquals("cache size does not match", keys.size(), os.size());
for (String key : keys) {
if (!os.contains(key))
Assert.fail(String.format("cache does not contain key %s", key));
}
} catch (Exception e) {
failWith(String.format("error getting cache keys of domain %s: %s", domain, e.getMessage()), e);
} finally {
try {
cache.clear(domain);
} catch (Exception e) {
; // ignore
}
}
return statistics;
}
where I write
this.cache.put(domain, key, resource);a few entities to the database and then, when querying them with
Set<Object> os = cache.getKeys(domain);the set is empty.
Can you give me a hint on what is going wrong here? When running the test against a single cache only (so one session factory involved)
then everything works fine.
regards, Chris