Java junit tests fails with "object already exists" after upgrade from h2 1.4.199 to 2.2.224

215 views
Skip to first unread message

Knut Skomedal

unread,
Oct 24, 2023, 1:55:42 PM10/24/23
to H2 Database
Does anyone know how to configure h2 version 2.2.224 to drop in-memory tables between unit tests, or accept that they already exist?

The code in question runs a number of junit tests using an in-memory h2 database.
All of them fails to create the spring applicationcontext when I upgrade the h2-version past 1.4.199:

o.s.test.context.TestContextManager: Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener] to prepare test instance [my testclass]
java.lang.IllegalStateException: Failed to load ApplicationContext

LocalContainerEntityManagerFactoryBean: Failed to initialize JPA EntityManagerFactory Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.GenericJDBCException: Unable to open JDBC Connection for DDL execution
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error: "java.lang.RuntimeException: object already exists" [50000-224]

I'm guessing that the problem lies in a failure to drop the tables created by the previous test class. 
I've tried all the tips I found at this link (https://blog.kie.org/2023/08/tip-h2-upgrade.html) and read through the available options for the constructor of the h2server, but I haven't found anything that allows the applicationContext to be created.

The tests are using "org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" as the jpaVendorAdapter of org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.
This bean has properties:
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.use_sql_comments">true</prop>
                <prop key="hibernate.check_nullability">true</prop>
                <prop key="hibernate.id.new_generator_mappings">true</prop>
                <prop key="hibernate.jdbc.batch_size">100</prop>
                <prop key="hibernate.cache.use_second_level_cache">false</prop>
                <prop key="hibernate.order_inserts">true</prop>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
                <prop key="javax.persistence.schema-generation.drop-source">script</prop> <-- tested based on the linked article
                <prop key="javax.persistence.schema-generation.drop-script-source">${project.basedir}/src/test/resources/drop-tables.sql</prop>  <-- tested based on the linked article
            </props>
        </property>

The drop-tables.sql script contains 
DROP ALL OBJECTS

The h2server is defined with:
    <bean id="h2Server" class="org.h2.tools.Server" factory-method="createTcpServer" init-method="start" destroy-method="stop" depends-on="h2WebServer">
        <constructor-arg value="-tcp,-tcpAllowOthers,-tcpPort,9092"/>
    </bean>

I've attempted to add the -ifNotExists option, with no effect.

The datasource:
    <bean id="dataSource" class="org.h2.jdbcx.JdbcDataSource">
        <property name="URL"
                  value="jdbc:h2:mem:name;MODE=Oracle;DB_CLOSE_DELAY=-1;TRACE_LEVEL_SYSTEM_OUT=0;LOCK_TIMEOUT=60000;DB_CLOSE_ON_EXIT=FALSE"/>
        <property name="user" value="public"/>
    </bean>

I've tested MODE=LEGACY with no effect

Noel Grandin

unread,
Oct 25, 2023, 2:13:54 AM10/25/23
to h2-da...@googlegroups.com, Knut Skomedal
On 10/24/2023 5:01 PM, Knut Skomedal wrote:
> Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error: "java.lang.RuntimeException: object already exists"
> [50000-224]

Can you post the actual stacktrace of this part ?

Knut Skomedal

unread,
Oct 25, 2023, 3:00:06 AM10/25/23
to Noel Grandin, h2-da...@googlegroups.com
Here's the full stacktrace:
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:98)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:124)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:248)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:365)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:273)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:159)
at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:383)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:344)
at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:125)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:417)
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'entityManagerFactory' defined in class
path resource [h2/h2-tilkobling.xml]: Invocation of init method
failed; nested exception is javax.persistence.PersistenceException:
[PersistenceUnit: default] Unable to build Hibernate SessionFactory;
nested exception is org.hibernate.exception.GenericJDBCException:
Unable to open JDBC Connection for DDL execution
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:127)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:276)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:244)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:141)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:90)
... 28 common frames omitted
Caused by: javax.persistence.PersistenceException: [PersistenceUnit:
default] Unable to build Hibernate SessionFactory; nested exception is
org.hibernate.exception.GenericJDBCException: Unable to open JDBC
Connection for DDL execution
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
... 43 common frames omitted
Caused by: org.hibernate.exception.GenericJDBCException: Unable to
open JDBC Connection for DDL execution
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:71)
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.jdbcStatement(GenerationTargetToDatabase.java:77)
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:53)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.applySqlString(SchemaDropperImpl.java:387)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.applySqlStrings(SchemaDropperImpl.java:371)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.dropFromMetadata(SchemaDropperImpl.java:246)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.performDrop(SchemaDropperImpl.java:156)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:128)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:114)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:157)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:85)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:335)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:471)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1498)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
... 47 common frames omitted
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error:
"java.lang.RuntimeException: object already exists" [50000-224]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:566)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:489)
at org.h2.message.DbException.get(DbException.java:212)
at org.h2.message.DbException.convert(DbException.java:407)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:345)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:125)
at org.h2.jdbcx.JdbcDataSource.getConnection(JdbcDataSource.java:155)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:181)
at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:44)
... 63 common frames omitted
Caused by: java.lang.RuntimeException: object already exists
at org.h2.message.DbException.getInternalError(DbException.java:355)
at org.h2.engine.Database.addDatabaseObject(Database.java:939)
at org.h2.engine.Database.setMasterUser(Database.java:1718)
at org.h2.engine.Engine.openSession(Engine.java:107)
at org.h2.engine.Engine.openSession(Engine.java:222)
at org.h2.engine.Engine.createSession(Engine.java:201)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:343)
... 68 common frames omitted

Knut Skomedal

unread,
Oct 25, 2023, 3:16:50 AM10/25/23
to Noel Grandin, h2-da...@googlegroups.com
In addition, the h2 database is initialized by running scripts that
fits the chosen profile of the project.

<jdbc:initialize-database data-source="dataSource"
ignore-failures="DROPS"> <-- it's set to ignore failures from dropping
the tables, maybe this no longer works as before?
<jdbc:script location="classpath:sql/quartz/tables_h2.sql"/>
</jdbc:initialize-database>

Noel Grandin

unread,
Oct 25, 2023, 3:27:47 AM10/25/23
to Knut Skomedal, h2-da...@googlegroups.com
My best guess right now is that you are using named in-memory databases, which means that the unit tests are sharing an
in-memory database, and you are hitting a race condition (TOCTOU) in that chunk of code.

Short of fixing the H2 code, the only thing I can suggest is using different databases for different unit tests.

Knut Skomedal

unread,
Oct 25, 2023, 5:08:39 AM10/25/23
to Noel Grandin, h2-da...@googlegroups.com
The same Exception occurs when I run a single test manually in
intelliJ, so I doubt that it's a race condition between two tests.

By setting a breakpoint where the previous stacktrace has the last statement:
Caused by: java.lang.RuntimeException: object already exists
at org.h2.message.DbException.getInternalError(DbException.java:355)
I find an OutOfMEmoryError:

serialVersionUID = 1
HIDE_SQL = "--hide--"
MESSAGES = {Properties@5409} size = 202
SQL_OOME = {SQLException@5410} "java.sql.SQLException: OutOfMemoryError"
SQLState = "HY000"
vendorCode = 90108
next = null
backtrace = {Object[6]@7812}
detailMessage = "OutOfMemoryError"
cause = {OutOfMemoryError@7813} "java.lang.OutOfMemoryError"
stackTrace = {StackTraceElement[63]@7815}
0 = {StackTraceElement@7817}
"org.h2.message.DbException.<clinit>(DbException.java:62)"
1 = {StackTraceElement@7818}
"org.h2.message.TraceObject.<clinit>(TraceObject.java:108)"
2 = {StackTraceElement@7819}
"java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native
Method)"
3 = {StackTraceElement@7820}
"java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)"
4 = {StackTraceElement@7821}
"java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)"
5 = {StackTraceElement@7822}
"java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)"
6 = {StackTraceElement@7823}
"java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)"
7 = {StackTraceElement@7824}
"org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:211)"
8 = {StackTraceElement@7825}
"org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87)"
9 = {StackTraceElement@7826}
"org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1326)"
10 = {StackTraceElement@7827}
"org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232)"
11 = {StackTraceElement@7828}
"org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)"
12 = {StackTraceElement@7829}
"org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)"
13 = {StackTraceElement@7830}
"org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)"
14 = {StackTraceElement@7831}
"org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)"
15 = {StackTraceElement@7832}
"org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)"
16 = {StackTraceElement@7833}
"org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)"
17 = {StackTraceElement@7834}
"org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:330)"
18 = {StackTraceElement@7835}
"org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:113)"
19 = {StackTraceElement@7836}
"org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1707)"
20 = {StackTraceElement@7837}
"org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1452)"
21 = {StackTraceElement@7838}
"org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619)"
22 = {StackTraceElement@7839}
"org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)"
23 = {StackTraceElement@7840}
"org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)"
24 = {StackTraceElement@7841}
"org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)"
25 = {StackTraceElement@7842}
"org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)"
26 = {StackTraceElement@7843}
"org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)"
27 = {StackTraceElement@7844}
"org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154)"
28 = {StackTraceElement@7845}
"org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908)"
29 = {StackTraceElement@7846}
"org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)"
30 = {StackTraceElement@7847}
"org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:127)"
31 = {StackTraceElement@7848}
"org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)"
32 = {StackTraceElement@7849}
"org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:276)"
33 = {StackTraceElement@7850}
"org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:244)"
34 = {StackTraceElement@7851}
"org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:141)"
35 = {StackTraceElement@7852}
"org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:90)"
36 = {StackTraceElement@7853}
"org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:124)"
37 = {StackTraceElement@7854}
"org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118)"
38 = {StackTraceElement@7855}
"org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)"
39 = {StackTraceElement@7856}
"org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:248)"
40 = {StackTraceElement@7857}
"org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)"
41 = {StackTraceElement@7858}
"org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)"
42 = {StackTraceElement@7859}
"org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)"
43 = {StackTraceElement@7860}
"org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)"
44 = {StackTraceElement@7861}
"org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)"
45 = {StackTraceElement@7862}
"org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)"
46 = {StackTraceElement@7863}
"org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)"
47 = {StackTraceElement@7864}
"org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)"
48 = {StackTraceElement@7865}
"org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)"
49 = {StackTraceElement@7866}
"org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)"
50 = {StackTraceElement@7867}
"org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)"
51 = {StackTraceElement@7868}
"org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)"
52 = {StackTraceElement@7869}
"org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)"
53 = {StackTraceElement@7870}
"org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)"
54 = {StackTraceElement@7871}
"org.junit.runners.ParentRunner.run(ParentRunner.java:413)"
55 = {StackTraceElement@7872}
"org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)"
56 = {StackTraceElement@7873}
"org.junit.runner.JUnitCore.run(JUnitCore.java:137)"
57 = {StackTraceElement@7874}
"com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)"
58 = {StackTraceElement@7875}
"com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)"
59 = {StackTraceElement@7876}
"com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)"
60 = {StackTraceElement@7877}
"com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)"
61 = {StackTraceElement@7878}
"com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)"
62 = {StackTraceElement@7879}
"com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)"
depth = 63
suppressedExceptions = {Collections$EmptyList@5413} size = 0

Knut Skomedal

unread,
Oct 25, 2023, 8:46:55 AM10/25/23
to H2 Database
I've debugged the last part of the process  where hibernate tries to get a connection to the database, starting with a breakpoint in org.h2.engine.Engine.createSession(Engine.java:201)

    public static SessionLocal createSession(ConnectionInfo ci) {
        try {
            SessionLocal session = openSession(ci);

ci = {ConnectionInfo}
 prop = {Properties}  size = 5 <-- The properties are parsed correctly from the original url.
  "LOCK_TIMEOUT" -> "60000"
  "DB_CLOSE_DELAY" -> "-1"
  "MODE" -> "Oracle"
  "DB_CLOSE_ON_EXIT" -> "FALSE"
  "TRACE_LEVEL_SYSTEM_OUT" -> "0"
 originalURL = "jdbc:h2:mem:SVIFT;MODE=Oracle;DB_CLOSE_DELAY=-1;TRACE_LEVEL_SYSTEM_OUT=0;LOCK_TIMEOUT=60000;DB_CLOSE_ON_EXIT=FALSE"
 url = "jdbc:h2:mem:SVIFT"
 user = "PUBLIC"
 name = "mem:SVIFT"

This runs to L222: session = openSession(ci, ifExists, forbidCreation, cipher);
 ifExists (slot_1) = 0
forbidCreation (slot_2) = 0
ignoreUnknownSetting (slot_3) = 0
cipher (slot_4) = null

Then to L107:
                if (!found) {
                    // users is the last thing we add, so if no user is around,
                    // the database is new (or not initialized correctly)
                    user = new User(database, database.allocateObjectId(), ci.getUserName(), false);
                    user.setAdmin(true);
                    user.setUserPasswordHash(ci.getUserPasswordHash());
                    database.setMasterUser(user); <-- Here

public synchronized void setMasterUser(User user) {
        lockMeta(systemSession);
        addDatabaseObject(systemSession, user); <-- Here

systemSession:
result = {SessionLocal} "#0 (user: DBA, INIT)"
 serialId = 0
 database = {Database} "SVIFT:org.h2.engine.Database"
 user = {User} "DBA:0:org.h2.engine.User"
 id = 1
 networkConnectionInfo = null
 locks = {ArrayList}  size = 1
 autoCommit = true
 random = null
 lockTimeout = 2000
 nextValueFor = null
 currentValueFor = null
 lastIdentity = {ValueNul} "NULL"
 savepoints = null
 localTempTables = null
 localTempTableIndexes = null
 localTempTableConstraints = null
 throttleMs = 0
 lastThrottleNs = 0
 currentCommand = null
 allowLiterals = false
 currentSchemaName = "PUBLIC"
 schemaSearchPath = null
 trace = null
 removeLobMap = null
 systemIdentifier = 0
 procedures = null
 autoCommitAtTransactionEnd = false
 currentTransactionName = null
 cancelAtNs = 0
 sessionStart = {ValueTimestampTimeZone} "TIMESTAMP WITH TIME ZONE '2023-10-25 12:48:23.230424874+02'"
 commandStartOrEnd = {Instant} "2023-10-25T10:48:23.230424874Z"
 currentTimestamp = null
 variables = null
 queryTimeout = 0
 commitOrRollbackDisabled = false
 waitForLock = null
 waitForLockThread = null
 modificationId = 0
 objectId = 0
 queryCacheSize = 8
 queryCache = null
 modificationMetaID = -1
 createViewLevel = 0
 viewIndexCache = null
 derivedTableIndexCache = null
 lazyQueryExecution = false
 nonKeywords = null
 timeZone = {TimeZoneProvider$WithTimeZone} "TimeZoneProvider Europe/Oslo"
 tablesToAnalyze = null
 temporaryResultLobs = null
 temporaryLobs = null
 transaction = null
 state = {AtomicReference} "INIT"
 startStatement = -1
 isolationLevel = {IsolationLevel} "READ_COMMITTED"
 snapshotDataModificationId = 0
 idsToRelease = null
 truncateLargeLength = false
 variableBinary = false
 oldInformationSchema = false
 quirksMode = false
 lock = {ReentrantLock} "java.util.concurrent.locks.ReentrantLock[Unlocked]"
 sessionState = null
 sessionStateChanged = true
 sessionStateUpdating = false
 staticSettings = null

user = {User} "PUBLIC:2:org.h2.engine.User"
 systemUser = false
 salt = {byte[8]
 passwordHash = {byte[32]}
 admin = true
 grantedRoles = null
 grantedRights = null
 database = {Database} "SVIFT:org.h2.engine.Database"
 trace = {Trace}
 comment = null
 id = 2
 objectName = "PUBLIC"
 modificationId = 1
 temporary = false

Then to     public synchronized void addDatabaseObject(SessionLocal session, DbObject obj) { <-- obj is the User above
        int id = obj.getId();
        if (id > 0 && !starting) {
            checkWritingAllowed(); <-- OK
        }
        ConcurrentHashMap<String, DbObject> map = getMap(obj.getType()); <-- getMap(type = 2 which is USER) returns the content of Database.usersAndRoles
        if (obj.getType() == DbObject.USER) {
            User user = (User) obj;
            if (user.isAdmin() && systemUser.getName().equals(SYSTEM_USER_NAME)) {
                systemUser.rename(user.getName());
            }
        }
        String name = obj.getName(); <-- returns PUBLIC
        if (SysProperties.CHECK && map.get(name) != null) {
            throw DbException.getInternalError("object already exists"); <-- Enters this, both names are "PUBLIC".
        }

map (slot_4) = {ConcurrentHashMap}  size = 1
 "PUBLIC" -> {Role} "PUBLIC:0:org.h2.engine.Role"
  key = "PUBLIC"
  value = {Role} "PUBLIC:0:org.h2.engine.Role"
   system = true
   grantedRoles = null
   grantedRights = null
   database = {Database} "SVIFT:org.h2.engine.Database"
   trace = {Trace}
   comment = null
   id = 0
   objectName = "PUBLIC"
   modificationId = 0
   temporary = false

In the getInternalError()-method of DbException, the static content of the class contains the OutOfMemoryError posted previously. It might not be related to the problem that occurs.

Does any of this indicate to you what the problem is?

Knut Skomedal

unread,
Oct 25, 2023, 9:01:38 AM10/25/23
to H2 Database
When I'm running 1.4.199 the execution ends in the same method for addDatabaseObject(Session session, DbObject obj) which seems unchanged with a casual glance.

session = {Session} "#0 (user: DBA)"

 serialId = 0
 database = {Database} "SVIFT:org.h2.engine.Database"
 connectionInfo = null

 user = {User} "DBA:0:org.h2.engine.User"
 id = 1
 locks = {ArrayList}  size = 1
 undoLog = null

 autoCommit = true
 random = null
 lockTimeout = 2000
 lastIdentity = {ValueLong} "0"
 lastScopeIdentity = {ValueLong} "0"
 lastTriggerIdentity = null
 generatedKeys = null
 firstUncommittedLog = -1
 firstUncommittedPos = -1

 savepoints = null
 localTempTables = null
 localTempTableIndexes = null
 localTempTableConstraints = null
 throttleNs = 0
 lastThrottle = 0

 currentCommand = null
 allowLiterals = false
 currentSchemaName = "PUBLIC"
 schemaSearchPath = null
 trace = null
 removeLobMap = null
 systemIdentifier = 0
 procedures = null
 undoLogEnabled = true
 redoLogBinary = true

 autoCommitAtTransactionEnd = false
 currentTransactionName = null
 cancelAtNs = 0
 sessionStart = 1698238342161
 transactionStart = null
 currentCommandStart = null
 variables = null
 temporaryResults = null

 queryTimeout = 0
 commitOrRollbackDisabled = false
 waitForLock = null
 waitForLockThread = null
 modificationId = 0
 objectId = 0
 queryCacheSize = 8
 queryCache = null
 modificationMetaID = -1
 subQueryInfo = null
 viewNameStack = null
 preparingQueryExpression = 0
 viewIndexCache = null
 subQueryIndexCache = null
 joinBatchEnabled = false
 forceJoinOrder = false
 lazyQueryExecution = false
 columnNamerConfiguration = {ColumnNamerConfiguration}
 tablesToAnalyze = null
 temporaryResultLobs = null
 temporaryLobs = null
 transaction = null
 state = {AtomicReference} "INIT"
 startStatement = -1
 idsToRelease = null

 sessionState = null
 sessionStateChanged = true
 sessionStateUpdating = false

obj = {User} "PUBLIC:2:org.h2.engine.User"

 systemUser = false
 salt = {byte[8]
 passwordHash = {byte[32]
 admin = true
 grantedRoles = null
 grantedRights = null
 database = {Database} "SVIFT:org.h2.engine.Database@691500ab"

 trace = {Trace}
 comment = null
 id = 2
 objectName = "PUBLIC"
 modificationId = 1
 temporary = false

The getMap() method returns the content of the Database.user variable which has no content.
name is still "PUBLIC"
thus the test in 
    if (SysProperties.CHECK && map.get(name) != null)
isn't true and no exception is thrown.

Noel Grandin

unread,
Oct 25, 2023, 9:10:19 AM10/25/23
to h2-da...@googlegroups.com, Knut Skomedal
I think it's because you are using a username of "PUBLIC", which conflicts with something we have changed (not sure what).

"PUBLIC" is the name of the default schema and the default role, so it is no surprise that it conflicts.

Probably we should be throwing a better error message in that case.

Knut Skomedal

unread,
Oct 25, 2023, 9:45:50 AM10/25/23
to Noel Grandin, h2-da...@googlegroups.com
Thanks, changing the user in the JdbcDataSource definition solved the
problem. My tests are now running.

With regards,

Knut

Knut Skomedal

unread,
Oct 25, 2023, 9:50:01 AM10/25/23
to Noel Grandin, h2-da...@googlegroups.com
D'oh, I ran the tests with version 1.4.199 the first time, they're
still failing with 2.2.224, but I'm getting another error now (column
names that are reserved words). I can probably fix that.

Anyway, thanks for your help.
Reply all
Reply to author
Forward
0 new messages