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?
On Wednesday, 25 October 2023 at 11:08:39 UTC+2 Knut Skomedal wrote:
> 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
>
> On Wed, Oct 25, 2023 at 9:27 AM Noel Grandin <[email protected]> wrote:
> >
> > 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.
>
--
You received this message because you are subscribed to the Google Groups "H2
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/h2-database/c6f9b562-1b15-44de-b32b-3b832d7d9f48n%40googlegroups.com.