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. On Wednesday, 25 October 2023 at 14:46:55 UTC+2 Knut Skomedal wrote: > 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 <noelg...@gmail.com> 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 h2-database+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/h2-database/aed1475c-0c67-439b-a2ea-345bebb9323bn%40googlegroups.com.