如何修复使用H2插件(版本1.4.200)运行Spring测试时出现的错误:JdbcSQLSyntaxErrorException:未找到列“start_value”

14

我必须将Spring Boot starter从2.1.4.RELEASE更新到2.2.6.RELEASE,但现在集成测试失败了。

我的测试用例使用Groovy编写,我的应用程序则是用Java编写的。它们在之前的Spring版本(2.1.4)下运行良好。

在更新SpringBoot Starter版本后,在运行集成测试时日志中出现了一个新错误:

H2 - version

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
           <version>1.4.200</version>
            <scope>test</scope>
        </dependency>

这是日志信息:

====================== Init Spring ======================
2020-10-30 16:43:17.867  WARN 13275 --- [           main] kafka.server.BrokerMetadataCheckpoint    : No meta.properties file under dir /tmp/kafka-14845506122745551840/meta.properties
2020-10-30 16:43:19.651 ERROR 13275 --- [           main] o.h.e.j.e.internal.JdbcEnvironmentImpl   : Could not fetch the SequenceInformation from the database

org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "start_value" not found [42122-200]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:453)
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
    at org.h2.message.DbException.get(DbException.java:205)
    at org.h2.message.DbException.get(DbException.java:181)
    at org.h2.jdbc.JdbcResultSet.getColumnIndex(JdbcResultSet.java:3169)
    at org.h2.jdbc.JdbcResultSet.get(JdbcResultSet.java:3268)
    at org.h2.jdbc.JdbcResultSet.getLong(JdbcResultSet.java:680)
    at com.zaxxer.hikari.pool.HikariProxyResultSet.getLong(HikariProxyResultSet.java)
    at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.resultSetStartValueSize(SequenceInformationExtractorLegacyImpl.java:129)
    at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.extractMetadata(SequenceInformationExtractorLegacyImpl.java:59)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl.sequenceInformationList(JdbcEnvironmentImpl.java:403)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl.<init>(JdbcEnvironmentImpl.java:268)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:114)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
    at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:176)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:118)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1202)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1233)
    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:391)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:378)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1855)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1792)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1108)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
    at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:126)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:123)
    at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.postProcessFields(MockitoTestExecutionListener.java:95)
    at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.injectFields(MockitoTestExecutionListener.java:79)
    at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.prepareTestInstance(MockitoTestExecutionListener.java:54)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:244)
    at org.spockframework.spring.SpringTestContextManager.prepareTestInstance(SpringTestContextManager.java:56)
    at org.spockframework.spring.SpringInterceptor.interceptInitializerMethod(SpringInterceptor.java:43)
    at org.spockframework.runtime.extension.AbstractMethodInterceptor.intercept(AbstractMethodInterceptor.java:24)
    at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:97)
    at org.spockframework.runtime.BaseSpecRunner.invoke(BaseSpecRunner.java:475)
    at org.spockframework.runtime.BaseSpecRunner.runInitializer(BaseSpecRunner.java:341)
    at org.spockframework.runtime.BaseSpecRunner.runInitializer(BaseSpecRunner.java:336)
    at org.spockframework.runtime.BaseSpecRunner.initializeAndRunIteration(BaseSpecRunner.java:274)
    at org.spockframework.runtime.BaseSpecRunner.runSimpleFeature(BaseSpecRunner.java:266)
    at org.spockframework.runtime.BaseSpecRunner.doRunFeature(BaseSpecRunner.java:260)
    at org.spockframework.runtime.BaseSpecRunner$5.invoke(BaseSpecRunner.java:243)
    at org.spockframework.runtime.BaseSpecRunner.invokeRaw(BaseSpecRunner.java:484)
    at org.spockframework.runtime.BaseSpecRunner.invoke(BaseSpecRunner.java:467)
    at org.spockframework.runtime.BaseSpecRunner.runFeature(BaseSpecRunner.java:235)
    at org.spockframework.runtime.BaseSpecRunner.runFeatures(BaseSpecRunner.java:185)
    at org.spockframework.runtime.BaseSpecRunner.doRunSpec(BaseSpecRunner.java:95)
    at org.spockframework.runtime.BaseSpecRunner$1.invoke(BaseSpecRunner.java:81)
    at org.spockframework.runtime.BaseSpecRunner.invokeRaw(BaseSpecRunner.java:484)
    at org.spockframework.runtime.BaseSpecRunner.invoke(BaseSpecRunner.java:467)
    at org.spockframework.runtime.BaseSpecRunner.runSpec(BaseSpecRunner.java:73)
    at org.spockframework.runtime.BaseSpecRunner.run(BaseSpecRunner.java:64)
    at org.spockframework.runtime.Sputnik.run(Sputnik.java:63)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
    at org.junit.vintage.engine.execution.RunnerExecutor.execute(RunnerExecutor.java:40)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
    at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
    at org.junit.vintage.engine.VintageTestEngine.executeAllChildren(VintageTestEngine.java:80)
    at org.junit.vintage.engine.VintageTestEngine.execute(VintageTestEngine.java:71)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
    at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
    at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)

2020-10-30 16:43:19.949  WARN 13275 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 42122, SQLState: 42S22
2020-10-30 16:43:19.949 ERROR 13275 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : Column "start_value" not found [42122-200]
2020-10-30 16:43:22.920 ERROR 13275 --- [           main] o.s.boot.SpringApplication               : Application run failed

我的应用在测试中运行失败,但当我使用 SqlServer 启动时,它不会失败。

我使用 Spock (Groovy):

        <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-core</artifactId>
           <version>1.3-groovy-2.5</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-spring</artifactId>
           <version>1.3-groovy-2.5</version>
            <scope>test</scope>
        </dependency>

application-test.yml:

spring:
  profiles: test
  groovy:
    template:
      check-template-location: false
  datasource:
    driver-class-name: org.h2.Driver
    url: "jdbc:h2:mem:myDb;MODE=MSSQLServer;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"
    username: sa
    password:
    platform: h2
    continue-on-error: true
    initialization-mode: embedded
    hikari:
      driver-class-name: org.h2.Driver
      jdbc-url: "jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"
  jpa:
    properties:
      hibernate:
        jdbc:
          batch_size: 50
          batch_versioned_data: true
          fetch_size: 100
        order_inserts: true
        order_updates: true
        new_generator_mappings: true
        show_sql: false
        format_sql: false
        connection:
          release_mode: after_transaction
    hibernate:
      ddl-auto: update
      use-new-id-generator-mappings: false
    database-platform: org.hibernate.dialect.H2Dialect
    open-in-view: false
    generate-ddl: true

请添加失败测试的代码。 - bovino Marcelo Bezerra
2
最近的Hibernate中使用SequenceInformationExtractorLegacyImpl与即将推出的H2 2.0的快照版本,但不适用于H2 1.4.200。对于您的版本,H2方言使用SequenceInformationExtractorH2DatabaseImpl。这样的堆栈跟踪看起来像是使用了错误的方言或其他一些模糊的问题。在JdbcEnvironmentImpl.sequenceInformationList()中设置断点可能有助于弄清楚发生了什么。 - Evgenij Ryazanov
@EvgenijRyazanov 谢谢您的回复。但我不明白要改变什么,也许是改变方言? - Rita Pissarra
抱歉,我不熟悉Hibernate。但是根据此条件,Hibernate的H2Dialect不应该使用SequenceInformationExtractorLegacyImpl与您的H2版本:https://github.com/hibernate/hibernate-orm/blob/67fd24ecff9f9a9a2e848805c04590b4b4ee2b3e/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java#L108-L110 - Evgenij Ryazanov
3个回答

17

感谢 @EvgenijRyazanov!当我调试时,我发现方言错误了:

org.hibernate.dialect.SQLServer2012Dialect

然后我查看了application-test.yml并添加了:

spring.jpa.properties.hibernate.dialect: org.hibernate.dialect.H2Dialect

它解决了我的问题!


不错的发现。在测试中使用H2而不是psql,这解决了问题。 - Tanel

3
我用的解决方法是在application.yml或application.properties文件中设置:
jpa.properties.hibernate.ddl-auto to "create" or to "none"

修改此设置解决了我的问题,但这会改变数据库初始化的行为,因此可能不是您想要的。

0
在我的特定情况下,问题是我应用程序版本与本地运行的 H2 实例之间的不匹配,我正在以服务器模式使用它。
  • 本地运行1.4.x
  • 应用程序使用2.x

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接