Bislang habe ich DBUnit-Tests immer auf einer MySql-Datenbank ausgeführt und möchte nun auf H2-Inmemory wechseln.
Das klappt noch nicht, daher beschreibe ich ersteinmal den Testaufbau mit MySql.
Konfiguration:
Code:
AnnotationConfiguration config = new AnnotationConfiguration()
.setProperty("hibernate.dialect", dialect)
.setProperty("hibernate.connection.driver_class", driver)
.setProperty("hibernate.connection.url", connectionPath + databaseName)
.setProperty("hibernate.connection.username", username)
.setProperty("hibernate.connection.password", password)
.setProperty("hibernate.connection.charSet", "UTF-8")
.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.HashtableCacheProvider")
.setProperty("hibernate.hbm2ddl.auto", autoStrategy.getName());
Um etwas zu testen, mache ich:
- Session aus bereits erstellter SessionFactory öffnen via openSession()
- z.B. DAO testen
- StatelessSession öffnen
- Daten via StatelessSession nachprüfen via openStatelessSession()
- beide Sessions schließen
Für die H2-DB habe ich die Konfiguration angepasst:
Code:
AnnotationConfiguration config = new AnnotationConfiguration()
.setProperty("hibernate.dialect", dialect)
.setProperty("hibernate.connection.driver_class", driver)
.setProperty("hibernate.connection.url", connectionPath + databaseName)
.setProperty("hibernate.connection.username", username)
.setProperty("hibernate.connection.password", password)
.setProperty("hibernate.connection.charSet", "UTF-8")
.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.HashtableCacheProvider")
.setProperty("hibernate.hbm2ddl.auto", autoStrategy.getName())
.setProperty("hibernate.current_session_context_class", "thread")
Wenn ich nun aber meine Tests ablaufen lassen, gibt es bei Nutzung der jeweils zweiten Session
einen Timeout aufgrund eines Locks.
Code:
org.hibernate.exception.GenericJDBCException: could not load an entity: [TestTable#1]
...
Caused by: org.h2.jdbc.JdbcSQLException: Zeitüberschreitung beim Versuch die Tabelle TestTable zu sperren
...
Timeout trying to lock table TestTable [50200-67]
Es hat ein wenig gedauert, bis ich bemerkt habe, dass es generell an der zweiten Session liegt. Meine Vermutung ist
daher, dass der Sessionpool nur eine herausrückt, aber keine zweite liefern kann (obwohl der Fehler nach etwas anderem
klingt ..). Nutze ich nämlich getCurrentSession() (gebunden an den jeweiligen Thread), funktioniert es tadellos.
Daher habe ich versucht, den Pool zu konfigurieren:
Code:
.setProperty("c3p0.acquire_increment", "1")
.setProperty("c3p0.idle_test_period", "100")
.setProperty("c3p0.max_size", "100")
.setProperty("c3p0.max_statements", "0")
.setProperty("c3p0.min_size", "10")
.setProperty("c3p0.timeout", "100");
Scheinbar habe ich hier aber etwas vergessen, denn dies hat keine Auswirkung auf die Verbindung (oder ich irre mich doch!),
denn der Timeout kommt noch immer nach etwa 1sek - ich hatte erwartet, dass das Problem sich löst oder zumindest ein Timeout
von 100sek angesetzt wird.
Weiß jemand, woran es liegt?
Auch würde mich interessieren, warum das Problem bei einer MySql Konfiguration nicht auftaucht.