【问题标题】:java h2 in-memory database error: Table not foundjava h2内存数据库错误:找不到表
【发布时间】:2016-08-07 13:07:01
【问题描述】:

我尝试用谷歌搜索,但几乎所有此类问题的解决方案是添加;DB_CLOSE_DELAY=-1,但它并没有为我解决任何问题。

这是我的测试课

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {Main.class})
public class Testas {

    @Autowired
    @Qualifier("managerImplementation")
    private ClassifierManager manager;

    @Test
    public void testManager(){
        ClassifierGroupEntity cge = new ClassifierGroupEntity();
        manager.saveClassifierGroup(cge);
    }
}

经理类

@Service("managerImplementation")
public class ClassifierManagerImpl implements ClassifierManager{

    @Autowired
    private ClassifierGroupEntityRepository groupEntityRepository;

    @Autowired
    private ClassifierEntityRepository entityRepository;

    @Autowired 
    private ClassifierValueEntityRepository valueEntityRepository;

    @Override
    public ClassifierGroupEntity getClassifierGroup(long id) {
        return groupEntityRepository.findOne(id);
    }

    @Override
    public ClassifierGroupEntity getClassifierGroup(String code) {
        return groupEntityRepository.findByCode(code);
    }

    @Override
    public ClassifierGroupEntity saveClassifierGroup(ClassifierGroupEntity entity) {
        return groupEntityRepository.save(entity);
    }

    @Override
    public void deleteClassifierGroup(long id) {
        groupEntityRepository.delete(id);
    }

    @Override
    public ClassifierEntity getClassifier(long id) {
        return entityRepository.findOne(id);
    }

    @Override
    public ClassifierEntity getClassifier(String code) {
        return entityRepository.findByCode(code);
    }

    @Override
    public ClassifierEntity saveClassifier(ClassifierEntity entity) {
        return entityRepository.save(entity);
    }

    @Override
    public void deleteClassifier(long id) {
        entityRepository.delete(id);
    }

    @Override
    public ClassifierValueEntity getClassifierValue(long id) {
        return valueEntityRepository.findOne(id);
    }

    @Override
    public ClassifierValue getClassifierValue(String classifiedCode, String valueCode) {
        return null;
    }

    @Override
    public ClassifierValueEntity saveClassifierValue(ClassifierValueEntity entity) {
        return valueEntityRepository.save(entity);
    }

    @Override
    public void deleteClassifierValue(long id) {
        valueEntityRepository.delete(id);
    }


}

最后是属性文件

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.user=sa
spring.datasource.password=
spring.datasource.url=jdbc:h2:mem:test;DB_CLOSE_DELAY=-1

启动测试让我失望

org.h2.jdbc.JdbcSQLException: Table "CLASSIFIER_GROUP_ENTITY" not found; SQL statement:
insert into classifier_group_entity (id, code, modified_details, modified_time, modified_user_id, order, revision, valid_details, valid_from, valid_till, parent_id) values (null, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [42102-191]

我不知道我是否应该提供其他任何东西,如果需要,请告诉我。提前感谢您的帮助。

【问题讨论】:

  • 这意味着您的内存数据库中的 H2 未初始化。如果您使用的是 Hibernate,您可以使用 进行测试吗?如果没有,您可以提供将创建您的架构的 sql。
  • 你在哪里初始化你的数据库?您在哪里加载 SQL 以创建模式(和表)?
  • 我不知道,我猜?我认为 spring jpa 为我创造了它们。我的意思是我第一次这样做时它对我来说效果很好(创建扩展 CrudRepository 的接口,然后只要求使用@Autowired 实现它)。抱歉,如果这听起来很愚蠢,我对所有这些东西都很陌生。
  • 在你的休眠配置中的某个地方,如果缺少,你需要启用创建模式的能力。在 /hibernate-configuration/session-factory 下的 hibernate.cfg.xml 中,我有: createupdate 根据需要创建表格。我还在我的实体上使用@Table(name="..."),所以它知道需要什么表。

标签: java spring jdbc h2


【解决方案1】:

添加 spring.jpa.defer-datasource-initialization=true

不要忘记在 application.properties/application.yaml 文件中添加这些值

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.show-sql=true
spring.h2.console.enabled=true
spring.jpa.defer-datasource-initialization=true

【讨论】:

    【解决方案2】:

    未找到表,因为在尝试创建表时开始出错。错误是由于ClassifierGroupEntity字段之一被命名为'order',这是SQL中的保留字之一,因此Spring生成的SQL语句在语法上是错误的。

    【讨论】:

    • 一般错误。唯一有用的是上面几十行之类的“无效的 SQL 语句:...”。但是,如果你看到了,我认为你不需要更多的谷歌搜索。 Unlikely help others告诉人们检查他们的字段名称不太可能帮助其他人怎么办??
    • 你为我节省了几个小时......谢谢
    • 天哪,很高兴我找到了你的答案
    • 谢谢,我的测试配置文件的休眠方言配置错误,因此生成的 ddl 语句包括一些 mysql 特定的 ddl 语句
    【解决方案3】:

    我参加聚会可能有点晚了,但我遇到了完全相同的错误,我尝试了这里和其他网站上提到的几乎所有解决方案,例如 DATABASE_TO_UPPER=false;DB_CLOSE_DELAY=-1; DB_CLOSE_ON_EXIT=假;忽略=真

    但对我没有任何帮助。 对我有用的是将 data.sql 重命名为 import.sql

    我在这里找到了 - https://stackoverflow.com/a/53179547/8219358

    或者

    对于 Spring Boot 2.4+,在 application.properties 中使用 spring.jpa.defer-datasource-initialization=true(此处提到 - https://stackoverflow.com/a/68086707/8219358)

    我意识到其他解决方案更合乎逻辑,但没有一个对我有用,而且确实如此。

    【讨论】:

    • 感谢 import.sql 为我完成了这项工作:)
    【解决方案4】:

    请尝试这个问题 -

    spring.datasource.url=jdbc:h2:mem:testdb;MODE=MySQL;DB_CLOSE_DELAY=-1;IGNORECASE=TRUE;
    

    【讨论】:

      【解决方案5】:

      在编写集成测试之前,我总是对 H2 数据库、Flyway、Spring Boot JPA 使用以下配置 - https://gist.github.com/vslala/d412156e5840fafa1b9f61aae5b20951

      将以下配置放入您的src/test/resources/application.properties 文件中。

      # Datasource configuration for jdbc h2
      # this is for file based persistent storage
      # spring.datasource.url=jdbc:h2:file:/data/demo
      
      # For in-memory storage
      spring.datasource.url=jdbc:h2:mem:testdb;MODE=MySQL;DB_CLOSE_DELAY=-1;IGNORECASE=TRUE;
      spring.datasource.driverClassName=org.h2.Driver
      spring.datasource.username=vslala
      spring.datasource.password=simplepass
      spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
      
      # This has to be over-ridden because
      # it's not kept create rather kept none or validate after the first ddl creation.
      spring.jpa.generate-ddl=true
      spring.jpa.hibernate.ddl-auto=create
      
      # This is for FlyWay configuration
      spring.flyway.url=jdbc:h2:mem:testdb
      spring.flyway.schemas=testdb
      spring.flyway.user=vslala
      spring.flyway.password=simplepass
      

      【讨论】:

      • 投票!我只需要告诉 flyway 忽略 case spring.flyway.url=jdbc:h2:mem:testdb;MODE=MySQL;DB_CLOSE_DELAY=-1;IGNORECASE=TRUE;
      • @Tinkerbell 是的...过去也困扰过我:D
      • 我在几个小时后就陷入了同样的问题,但在搜索了很多之后没有找到正确的解决方案。最后感谢您的解决方案。我添加了 MODE=MySQL 以使其正常工作。
      【解决方案6】:

      在我的例子中,当定义查询时,我对列使用小写语法,但 H2 数据库中的列以大写形式定义。我希望忽略区分大小写,但 H2 数据库并非如此。

      【讨论】:

        【解决方案7】:

        在我的情况下,我很笨,忘记实际放入 spring.datasource.url

        由于某种原因,如果 JPA 找不到实际的数据库 url,它不会抛出错误。奇怪

        【讨论】:

          【解决方案8】:

          我在为自己的应用程序编写单元测试时遇到了同样的问题。经过多次尝试,我无法让我的应用程序测试用例运行。我在 1.4.191 版本上运行,然后升级到 1.4.196 并开始工作。

          【讨论】:

            【解决方案9】:

            在 src/test/resources 文件夹中的 application.properties 文件中包含这些属性:

            spring.jpa.generate-ddl=true

            spring.jpa.hibernate.ddl-auto=create

            这必须被覆盖,因为在第一次创建 ddl 后它没有保持 create 而是保持 none 或 validate。

            【讨论】:

              【解决方案10】:

              我在表中添加了几列后得到了这个。持久性生成器在我的实体中创建了更多字段。

              我在日志中注意到了这一点。

              ERROR 13691 --- [           main] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000389: Unsuccessful: create table comment
              ERROR 13691 --- [           main] org.hibernate.tool.hbm2ddl.SchemaExport  : Scale($"0") must not be bigger than precision("-1")
              

              事实证明,当我的 IDE 的持久性生成器映射我的 TEXT 字段时,它的长度为 -1。

              @Basic
              @Column(name = "address", nullable = true, length = -1)
              public String getAddress() {
                return address;
              }
              

              删除长度属性为我解决了问题。

              【讨论】:

                猜你喜欢
                • 2011-08-11
                • 2016-06-08
                • 2015-03-27
                • 2022-11-21
                • 2017-06-16
                • 2019-10-06
                • 2022-11-18
                • 2021-07-22
                • 1970-01-01
                相关资源
                最近更新 更多