【问题标题】:H2 server DB created through Spring not accessible通过 Spring 创建的 H2 服务器数据库无法访问
【发布时间】:2014-12-30 16:15:55
【问题描述】:

我使用的版本:

  • 春季版:4.0.5.RELEASE
  • H2 版本:1.3.174
  • 休眠版本:4.3.6.Final

我曾经有一个工作设置,在部署战争文件时,我使用我的 applicationContext 创建了一个 H2 服务器和一个数据源。我的配置是这样的:

<bean id = "h2Server"
      class="org.h2.tools.Server"
      factory-method="createTcpServer"
      init-method="start"
      destroy-method="stop">
    <constructor-arg value="-tcp,-tcpAllowOthers,-tcpPort,8045" />
</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" depends-on="h2Server">
  <property name="driverClassName" value="org.h2.Driver" />
  <property name="url" value="${database.url}" />
  <property name="username" value="${database.username}" />
  <property name="password" value="${database.password}" />

然后我定义了一个

LocalContainerEntityManagerFactoryBean

定义 jpaProperty 让 hibernate 自动生成所有表:

<property name="jpaProperties">
    <props>
        <prop key="hibernate.hbm2ddl.auto">update</prop>
        <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
    </props>
</property>

这就像一个魅力,当我的应用程序被部署时,所有的表都是自动创建的。这对于测试设置非常有用,但对于生产版本,我们希望关闭 hibernate 自动生成表,并且我们希望自己管理 sql 创建和迁移脚本。

因此我决定使用 flyway 作为数据库迁移工具,并从 EntityManager 定义中删除了以下行:

 <prop key="hibernate.hbm2ddl.auto">update</prop>

这似乎可行,并且创建了数据库并且具有最小的大小,但是当我尝试使用 Squirrel 连接到它时,出现以下异常:

我希望如果 H2Server 和数据源 bean 是由 Spring 创建的,那么可以使用它的驱动程序、url、用户名、密码来访问数据库。

我的第一个想法是它们不是因为延迟初始化而创建的,而 hibernate 表的创建意味着要真正初始化 bean。我尝试将两个属性的延迟初始化属性都设置为false,但没有运气...

我一定是错过了什么,但现在看不到它...... 部署应用程序后,有没有办法使数据库可用于连接?

【问题讨论】:

    标签: java spring hibernate datasource h2


    【解决方案1】:

    您在客户端使用 H2 版本 1.4.181。 (错误代码的最后一部分,90067-181,是H2的内部版本号)。

    在服务器端,您写道您使用的是 H2 版本 1.3.174。

    问题很可能是 H2 客户端和 H2 服务器之间不兼容。从理论上讲,这应该不是问题,但看起来 H2 中存在一个错误,导致这些版本无法协同工作。

    我建议也将服务器升级到 1.3.181,并将;mv_store=false 附加到数据库 URL 以禁用仍处于测试阶段的新存储引擎。

    【讨论】:

    • 感谢您的回复。我尝试了您的解决方案,但不幸的是没有运气......我无法在使用 Java 代码部署后立即连接到数据库,所以我认为它真的不可用并且我的 spring 配置中有错误......
    【解决方案2】:

    我找到了解决方案:一切正常。我在 org.h2.tools.Server 类的 start 和 stop 方法中放置了一个断点,并在将应用程序部署到我的 tomcat 服务器时激活了远程调试。

    我注意到服务器启动了,但过了一段时间,我也到达了停止方法。更深入的调查向我展示了 tomcat 命令中的以下几行:

    04-Nov-2014 13:00:28.240 SEVERE [localhost-startStop-1] org.apache.catalina.core
        .StandardContext.startInternal Error listenerStart
    04-Nov-2014 13:00:55.961 SEVERE [localhost-startStop-1] org.apache.catalina.core
        .StandardContext.startInternal Context [/healthdata_hd4res] startup failed due to previous errors
    

    然后在 localhost.log 文件中,我发现如下错误:

    Caused by: org.h2.jdbc.JdbcSQLException: Table "CONFIGURATIONS" not found; SQL statement:
        select configurat0_.CONFIGURATION_ID as CONFIGUR1_1_, configurat0_.DESCRIPTION as DESCRIPT2_1_, configurat0_.KEY as KEY3_1_, configurat0_.UPDATED_ON as UPDATED_4_1_, configurat0_.VALID_FROM as VALID_FR5_1_, configurat0_.VALID_TILL as VALID_TI6_1_, configurat0_.VALUE as VALUE7_1_ from CONFIGURATIONS configurat0_ where configurat0_.KEY=? and (configurat0_.VALID_FROM is null or configurat0_.VALID_FROM<=?) and (configurat0_.VALID_TILL is null or configurat0_.VALID_TILL>=?) [42102-174]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:332)
    at org.h2.message.DbException.get(DbException.java:172)
    

    有 2 个类实现了 ServletContextListener 以将数据注入现有表。由于尚未创建表,因此生成了错误,并且在部署期间我的 h2Server 已关闭...

    【讨论】:

    • 好的。这并不能解释您看到的异常(发布在问题中),但如果它现在有效,那么我想问题解决了:-)
    猜你喜欢
    • 2012-06-22
    • 2010-12-02
    • 2023-04-04
    • 2020-12-19
    • 2021-10-30
    • 2020-10-02
    • 2019-02-19
    • 2016-07-18
    • 2020-12-15
    相关资源
    最近更新 更多