簡體   English   中英

如何正確集成 HSQLDB 與 Spring 引導?

[英]How to correctly integrate HSQLDB with Spring Boot?

我看到了這篇文章: How to start HSQLDB in server mode from Spring boot application但無法使其正常工作。

我的目標是構建一個 Spring 啟動應用程序

  • 以服務器模式啟動 HSQLDB,並具有文件持久性(在我重新啟動應用程序時將其取回)
  • 公開與此 hsqldb 實例通信的公共 API
  • 讓我可以遠程連接到這個 hsqldb 服務器,例如使用包含在 hsqldb.jar 中的嵌入式 Swing 應用程序。

所以我試圖重現引用帖子的標記答案:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="hqlServer" class="org.hsqldb.server.Server" init-method="start" destroy-method="stop">
    <property name="properties"><bean class="org.hsqldb.persist.HsqlProperties">
        <constructor-arg><props>
        <prop key="server.database.0">file:/tmp/mydb.db</prop>
        <prop key="server.dbname.0">mydb</prop><!--DB name for network connection-->
        <prop key="server.no_system_exit">true</prop>
        <prop key="server.port">9001</prop><!--default port is 9001 -->
        <prop key="server.remote_open">true</prop>
        </props></constructor-arg>
    </bean></property>
</bean>
</beans>

我知道我接下來可以連接到jdbc:hsqldb:hsql://localhost:9001/mydb ,對吧?

好吧,我在 application.yml 中指定了所有參數

spring:
  profiles:
    active: dev
  datasource:
    driver-class-name: org.hsqldb.jdbc.JDBCDriver 
    url: jdbc:hsqldb:hsql://localhost:9001/mydb
    username: sa
    password: 
  jpa:
    database-platform: org.hibernate.dialect.HSQLDialect
    show-sql: true
    hibernate:
      ddl-auto: update 

最后,開發了 App 部分(Controller、Services 和 JPA 層)。

我還將 xml 部分包含在應用程序中

@SpringBootApplication
@ImportResource(value="classpath:/hsql_cfg.xml")
public class MyApp {
...
}

但是,顯然,它不起作用並給我以下錯誤:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
[32m :: Spring Boot :: [39m      [2m (v2.2.2.RELEASE)[0;39m

[2m2021-11-17 15:19:56.295[0;39m [32m INFO[0;39m [35m47627[0;39m [2m---[0;39m [2m[           main][0;39m [36mtest.MyApp                              [0;39m [2m:[0;39m Starting MyApp on iMac.local with PID 47627 (/Users/ludovic/workspace/test-hsqldb/target/classes started by ludovic in /Users/ludovic/workspace/test-hsqldb)
[2m2021-11-17 15:19:56.298[0;39m [32m INFO[0;39m [35m47627[0;39m [2m---[0;39m [2m[           main][0;39m [36mtest.MyApp                              [0;39m [2m:[0;39m The following profiles are active: dev
[2m2021-11-17 15:19:56.709[0;39m [32m INFO[0;39m [35m47627[0;39m [2m---[0;39m [2m[           main][0;39m [36m.s.d.r.c.RepositoryConfigurationDelegate[0;39m [2m:[0;39m Bootstrapping Spring Data JPA repositories in DEFAULT mode.
[2m2021-11-17 15:19:56.724[0;39m [32m INFO[0;39m [35m47627[0;39m [2m---[0;39m [2m[           main][0;39m [36m.s.d.r.c.RepositoryConfigurationDelegate[0;39m [2m:[0;39m Finished Spring Data repository scanning in 8ms. Found 0 JPA repository interfaces.
[2m2021-11-17 15:19:57.009[0;39m [32m INFO[0;39m [35m47627[0;39m [2m---[0;39m [2m[           main][0;39m [36mo.hibernate.jpa.internal.util.LogHelper [0;39m [2m:[0;39m HHH000204: Processing PersistenceUnitInfo [name: default]
[2m2021-11-17 15:19:57.057[0;39m [32m INFO[0;39m [35m47627[0;39m [2m---[0;39m [2m[           main][0;39m [36morg.hibernate.Version                   [0;39m [2m:[0;39m HHH000412: Hibernate Core {5.4.9.Final}
[2m2021-11-17 15:19:57.166[0;39m [32m INFO[0;39m [35m47627[0;39m [2m---[0;39m [2m[           main][0;39m [36mo.hibernate.annotations.common.Version  [0;39m [2m:[0;39m HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
[2m2021-11-17 15:19:57.241[0;39m [32m INFO[0;39m [35m47627[0;39m [2m---[0;39m [2m[           main][0;39m [36mcom.zaxxer.hikari.HikariDataSource      [0;39m [2m:[0;39m HikariPool-1 - Starting...
[2m2021-11-17 15:19:57.285[0;39m [31mERROR[0;39m [35m47627[0;39m [2m---[0;39m [2m[           main][0;39m [36mcom.zaxxer.hikari.pool.HikariPool       [0;39m [2m:[0;39m HikariPool-1 - Exception during pool initialization.

java.sql.SQLTransientConnectionException: java.net.ConnectException: Connection refused (Connection refused)
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.jdbc.JDBCConnection.<init>(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.jdbc.JDBCDriver$1.run(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
Caused by: org.hsqldb.HsqlException: java.net.ConnectException: Connection refused (Connection refused)
    at org.hsqldb.ClientConnection.openConnection(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.ClientConnection.initConnection(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.ClientConnection.<init>(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    ... 2 common frames omitted
Caused by: java.net.ConnectException: Connection refused (Connection refused)
    at java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:1.8.0_241]
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_241]
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_241]
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_241]
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_241]
    at java.net.Socket.connect(Socket.java:606) ~[na:1.8.0_241]
    at java.net.Socket.connect(Socket.java:555) ~[na:1.8.0_241]
    at java.net.Socket.<init>(Socket.java:451) ~[na:1.8.0_241]
    at java.net.Socket.<init>(Socket.java:228) ~[na:1.8.0_241]
    at org.hsqldb.server.HsqlSocketFactory.createSocket(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    ... 5 common frames omitted

[2m2021-11-17 15:19:57.286[0;39m [33m WARN[0;39m [35m47627[0;39m [2m---[0;39m [2m[           main][0;39m [36mo.h.e.j.e.i.JdbcEnvironmentInitiator    [0;39m [2m:[0;39m HHH000342: Could not obtain connection to query metadata : java.net.ConnectException: Connection refused (Connection refused)
[2m2021-11-17 15:19:57.296[0;39m [32m INFO[0;39m [35m47627[0;39m [2m---[0;39m [2m[           main][0;39m [36morg.hibernate.dialect.Dialect           [0;39m [2m:[0;39m HHH000400: Using dialect: org.hibernate.dialect.HSQLDialect
[2m2021-11-17 15:19:57.439[0;39m [32m INFO[0;39m [35m47627[0;39m [2m---[0;39m [2m[           main][0;39m [36mcom.zaxxer.hikari.HikariDataSource      [0;39m [2m:[0;39m HikariPool-1 - Starting...
[2m2021-11-17 15:19:57.441[0;39m [31mERROR[0;39m [35m47627[0;39m [2m---[0;39m [2m[           main][0;39m [36mcom.zaxxer.hikari.pool.HikariPool       [0;39m [2m:[0;39m HikariPool-1 - Exception during pool initialization.

java.sql.SQLTransientConnectionException: java.net.ConnectException: Connection refused (Connection refused)
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.jdbc.JDBCConnection.<init>(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.jdbc.JDBCDriver$1.run(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
Caused by: org.hsqldb.HsqlException: java.net.ConnectException: Connection refused (Connection refused)
    at org.hsqldb.ClientConnection.openConnection(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.ClientConnection.initConnection(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.ClientConnection.<init>(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    ... 2 common frames omitted
Caused by: java.net.ConnectException: Connection refused (Connection refused)
    at java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:1.8.0_241]
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_241]
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_241]
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_241]
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_241]
    at java.net.Socket.connect(Socket.java:606) ~[na:1.8.0_241]
    at java.net.Socket.connect(Socket.java:555) ~[na:1.8.0_241]
    at java.net.Socket.<init>(Socket.java:451) ~[na:1.8.0_241]
    at java.net.Socket.<init>(Socket.java:228) ~[na:1.8.0_241]
    at org.hsqldb.server.HsqlSocketFactory.createSocket(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    ... 5 common frames omitted

[2m2021-11-17 15:19:57.442[0;39m [33m WARN[0;39m [35m47627[0;39m [2m---[0;39m [2m[           main][0;39m [36mo.h.engine.jdbc.spi.SqlExceptionHelper  [0;39m [2m:[0;39m SQL Error: -1301, SQLState: 08001
[2m2021-11-17 15:19:57.442[0;39m [31mERROR[0;39m [35m47627[0;39m [2m---[0;39m [2m[           main][0;39m [36mo.h.engine.jdbc.spi.SqlExceptionHelper  [0;39m [2m:[0;39m java.net.ConnectException: Connection refused (Connection refused)
[2m2021-11-17 15:19:57.445[0;39m [33m WARN[0;39m [35m47627[0;39m [2m---[0;39m [2m[           main][0;39m [36ms.c.a.AnnotationConfigApplicationContext[0;39m [2m:[0;39m Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
[2m2021-11-17 15:19:57.450[0;39m [32m INFO[0;39m [35m47627[0;39m [2m---[0;39m [2m[           main][0;39m [36mConditionEvaluationReportLoggingListener[0;39m [2m:[0;39m 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
[2m2021-11-17 15:19:57.452[0;39m [31mERROR[0;39m [35m47627[0;39m [2m---[0;39m [2m[           main][0;39m [36mo.s.boot.SpringApplication              [0;39m [2m:[0;39m Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1108) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at test.MyApp.main(MyApp.java:11) [classes/:na]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:403) ~[spring-orm-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:378) ~[spring-orm-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1855) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1792) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    ... 15 common frames omitted
Caused by: org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
    at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:48) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:69) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.hibernate.tool.schema.internal.exec.ImprovedExtractionContextImpl.getJdbcConnection(ImprovedExtractionContextImpl.java:60) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.extractMetadata(SequenceInformationExtractorLegacyImpl.java:40) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.initializeSequences(DatabaseInformationImpl.java:65) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.<init>(DatabaseInformationImpl.java:59) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.hibernate.tool.schema.internal.Helper.buildDatabaseInformation(Helper.java:155) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:96) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:184) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:73) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:320) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:462) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1237) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:391) ~[spring-orm-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    ... 19 common frames omitted
Caused by: java.sql.SQLTransientConnectionException: java.net.ConnectException: Connection refused (Connection refused)
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.jdbc.JDBCConnection.<init>(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.jdbc.JDBCDriver$1.run(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
Caused by: org.hsqldb.HsqlException: java.net.ConnectException: Connection refused (Connection refused)
    at org.hsqldb.ClientConnection.openConnection(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.ClientConnection.initConnection(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.ClientConnection.<init>(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    ... 2 common frames omitted
Caused by: java.net.ConnectException: Connection refused (Connection refused)
    at java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:1.8.0_241]
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_241]
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_241]
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_241]
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_241]
    at java.net.Socket.connect(Socket.java:606) ~[na:1.8.0_241]
    at java.net.Socket.connect(Socket.java:555) ~[na:1.8.0_241]
    at java.net.Socket.<init>(Socket.java:451) ~[na:1.8.0_241]
    at java.net.Socket.<init>(Socket.java:228) ~[na:1.8.0_241]
    at org.hsqldb.server.HsqlSocketFactory.createSocket(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    ... 5 common frames omitted

我開始認為我的應用程序在服務器啟動之前嘗試連接,這可能嗎? 有沒有辦法告訴 Spring 首先啟動服務器,然后讓它變魔術?

謝謝

這些是相當“無條件的目標”,我不會稱其為“正確集成”,但你有 go:

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.6</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.stackoverflow</groupId>
    <artifactId>hsqldb-runner</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId><!-- as compile(!) dependency -->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId><!-- for the endpoints -->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId><!-- for simple jdbc access -->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

link的友好幫助下,一個額外的@Component注釋和一些Properties loading ,我們這樣做了:

package com.stackoverflow.hsqldbrunner;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Properties;

import org.hsqldb.Server;
import org.hsqldb.persist.HsqlProperties;
import org.hsqldb.server.ServerAcl.AclFormatException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.SmartLifecycle;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.stereotype.Component;

@Component
public class HyperSqlDbServer implements SmartLifecycle {
    private final Logger logger = LoggerFactory.getLogger(HyperSqlDbServer.class);
    private HsqlProperties properties;
    private Server server;
    private boolean running = false;

    public HyperSqlDbServer(@Value("classpath:/hsqldb.properties") Resource serverProps) throws IOException {
        Properties props = PropertiesLoaderUtils.loadProperties(serverProps);
        if (props.elements().hasMoreElements() && logger.isDebugEnabled()) {
            StringWriter writer = new StringWriter();
            props.list(new PrintWriter(writer));
            logger.debug(writer.toString());
        }
        properties = new HsqlProperties(props);
    }

    @Override
    public boolean isRunning() {
        if (server != null)
            server.checkRunning(running);
        return running;
    }

    @Override
    public void start() {
        if (server == null) {
            logger.info("Starting HSQL server...");
            server = new Server();
            try {
                server.setProperties(properties);
                server.start();
                running = true;
            } catch (AclFormatException afe) {
                logger.error("Error starting HSQL server.", afe);
            } catch (IOException e) {
                logger.error("Error starting HSQL server.", e);
            }
        }
    }

    @Override
    public void stop() {
        logger.info("Stopping HSQL server...");
        if (server != null) {
            server.stop();
            running = false;
        }
    }

    @Override
    public int getPhase() {
        return 0;
    }

    @Override
    public boolean isAutoStartup() {
        return true;
    }

    @Override
    public void stop(Runnable runnable) {
        stop();
        runnable.run();
    }
}

主類/配置/控制器:

package com.stackoverflow.hsqldbrunner;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class HsqldbRunnerApplication {

    @Autowired
    JdbcTemplate jdbcTemplate;

    public static void main(String[] args) {
        SpringApplication.run(HsqldbRunnerApplication.class, args);
    }

    @GetMapping("/query")
    public List<Map<String, Object>> query(@RequestParam String sql) {
        return jdbcTemplate.queryForList(sql);
    }

    @RequestMapping("/execute")
    public void execute(@RequestParam String sql) {
        jdbcTemplate.execute(sql);
    }
}

然后使用這個 src/main/resources/hsqldb.properties:

server.database.0=file:C:/hsqldb/demobase 
server.dbname.0=demobase
#server.database.n
#server.dbname.n    
server.silent=false 
server.trace=false
server.daemon=false
server.remote_open=true 

而這個 src/main/resources/application.properties

spring.datasource.url=jdbc:hsqldb:hsql://localhost/demobase
spring.datasource.user=SA
spring.datasource.password=

..當我們運行時:

mvn spring-boot:run

我們得到:

  • 以服務器模式啟動 HSQLDB,並具有文件持久性(在我重新啟動應用程序時將其取回)

看這里:

2021-11-17 17:35:58.652  INFO 3352 --- [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-11-17 17:35:58.652  INFO 3352 --- [  restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 313 ms
2021-11-17 17:35:58.780  INFO 3352 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2021-11-17 17:35:58.787  INFO 3352 --- [  restartedMain] c.s.hsqldbrunner.HyperSqlDbServer        : Starting HSQL server...
[Server@71142d78]: [Thread[restartedMain,5,main]]: start() entered
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: run() entered
[Server@71142d78]: Initiating startup sequence...
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: server.maxdatabases=10
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: server.remote_open=true
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: server.tls=false
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: server.daemon=false  
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: server.trace=false
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: server.database.0=file:C:/hsqldb/demobase 
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: server.restart_on_shutdown=false
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: server.no_system_exit=true
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: server.silent=false 
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: server.default_page=index.html
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: server.dbname.0=demobase
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: server.address=0.0.0.0
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: server.root=.
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: openServerSocket() entered
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: Got server socket: ServerSocket[addr=0.0.0.0/0.0.0.0,localport=9001]
[Server@71142d78]: Server socket opened successfully in 0 ms.
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: openServerSocket() exiting
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: openDatabases() entered
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: Opening database: [file:C:/hsqldb/demobase ]
[Server@71142d78]: Database [index=0, id=0, db=file:C:/hsqldb/demobase , alias=demobase] opened successfully in 0 ms.
[Server@71142d78]: [Thread[HSQLDB Server @71142d78,5,main]]: openDatabases() exiting
[Server@71142d78]: Startup sequence completed in 0 ms.
[Server@71142d78]: 2021-11-17 16:35:58.789 HSQLDB server 2.6.0 is online on port 9001
[Server@71142d78]: To close normally, connect and execute SHUTDOWN SQL
[Server@71142d78]: From command line, use [Ctrl]+[C] to abort abruptly
[Server@71142d78]: [Thread[restartedMain,5,main]]: start() exiting
2021-11-17 17:35:58.896  INFO 3352 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2021-11-17 17:35:58.900  INFO 3352 --- [  restartedMain] c.s.h.HsqldbRunnerApplication            : Started HsqldbRunnerApplication in 0.603 seconds (JVM running for 1330.867)
  • 公開與此 hsqldb 實例通信的公共 API:
  • /execute :執行(任意)sql 沒有預期的結果(jdbcTemplate.execute():void)
  • /query :查詢(對於List<Map<String, Object>>

例如,讓我們使用這個 sql 片段:

CREATE TABLE demo(id INT NOT NULL,title VARCHAR(50),submission_date DATE,PRIMARY KEY (id));

並將其發布到我們的瀏覽器,例如:

http://localhost:8080/execute?sql=CREATE%20TABLE%20demo(id%20INT%20NOT%20NULL,title%20VARCHAR(50),submission_date%20DATE,PRIMARY%20KEY%20(id))%3B

然后

INSERT INTO demo VALUES (1,'foo',now()),(2,'bar',now());

至:

http://localhost:8080/execute?sql=INSERT%20INTO%20demo%20VALUES%20(1%2C%27foo%27%2Cnow())%2C(2%2C%27bar%27%2Cnow())%3B

一個問題:

SELECT * FROM demo;

好像:

http://localhost:8080/query?sql=SELECT%20*%20FROM%20demo%3B

並返回:

[{"ID":1,"TITLE":"foo","SUBMISSION_DATE":"2021-11-17"},{"ID":2,"TITLE":"bar","SUBMISSION_DATE":"2021-11-17"}]
    
  • 讓我可以遠程連接到這個 hsqldb 服務器,例如使用包含在 hsqldb.jar 中的嵌入式 Swing 應用程序。

(遠程它必須經過測試,但是)從 localhost 看起來像這樣:

HSQLDB Swing 客戶端截圖

.. 我們得到(所有)hsqldb 服務器日志記錄到我們的 spring 應用程序。

所有組合在github repo中。 玩得開心,享受並且不要在生產中使用它; ;)


更多鏈接:

甚至用這個替換上面的服務器組件:

@Bean(initMethod = "start", destroyMethod = "stop")
public Server hsqlServer(@Value("classpath:/hsqldb.properties") Resource props) throws IOException, AclFormatException {
    Server bean = new org.hsqldb.server.Server();
    bean.setProperties(PropertiesLoaderUtils.loadProperties(props));
    return bean;
}

,類似於此 xml 配置,顯示沒有問題(像魅力一樣工作)。

但是,添加此依賴項:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

打破一切:(上下文不加載:)

Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set

一旦“修復”這個:

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect

我們得到異常:

...Caused by: java.net.ConnectException: Connection refused: connect

..在HikariPool的某個地方....


解決方案/解決方法:

import java.io.IOException;
import javax.sql.DataSource;
import org.hsqldb.server.Server;
import org.hsqldb.server.ServerAcl.AclFormatException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;

@SpringBootApplication
@EnableConfigurationProperties
public class HsqldbRunnerApplication {

    public static void main(String[] args) {
        SpringApplication.run(HsqldbRunnerApplication.class, args);
    }

    @Bean(initMethod = "start", destroyMethod = "stop")
    public Server hsqlServer(@Value("classpath:/hsqldb.properties") Resource props) throws IOException, AclFormatException {
        Server bean = new Server();
        bean.setProperties(PropertiesLoaderUtils.loadProperties(props));
        return bean;
    }

    @Bean
    @DependsOn("hsqlServer") // This is important!!
    public DataSource getDataSource(
            @Autowired DataSourceProperties dsProps) {
        DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
        dataSourceBuilder.driverClassName(dsProps.getDriverClassName());
        dataSourceBuilder.url(dsProps.getUrl());
        dataSourceBuilder.username(dsProps.getUsername());
        dataSourceBuilder.password(dsProps.getPassword());
        return dataSourceBuilder.build();
    }

}

所以,我們需要:

  • 定義我們自己的數據源bean,並依賴(讓它等待)我們的“hsqlServer”。

  • 將 Controller 移動到新的類(這還不錯,只是為了“簡潔”而存在),否則我們會得到循環依賴/未設置的數據源。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM