如何将 HSQLDB 与 Spring Boot 正确集成?
How to correctly integrate HSQLDB with Spring Boot?
我看到了这个 post : 但无法让它工作。
我的目标是构建一个 Spring 启动应用
- 以服务器模式启动 HSQLDB,具有文件持久性(以便在我重新启动我的应用程序时取回它)
- 公开与此 hsqldb 实例通信的 public API
- 让我可以远程连接到这个 hsqldb 服务器,例如使用 hsqldb.jar 中包含的嵌入式 Swing 应用程序。
所以我尝试重现引用post的标记答案:
<?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.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.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[=14=](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.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 首先启动服务器,然后发挥它的魔力?
谢谢
这些都是非常“无条件的目标”,我 不 称其为“正确整合”,但你去吧:
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.Whosebug</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><!-- just for fun -->
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId><!-- TODO! -->
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
在 link, an additional @Component
annotation and some Properties loading 的友好帮助下,我们这样做了:
package com.Whosebug.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();
}
}
主要class/Config/Controller:
package com.Whosebug.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
我们得到:
- Start HSQLDB in server mode, with file persistence (to get it back when I restart my app)
看这里:
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)
- Expose a public API that communicates with this hsqldb instance:
/execute
:执行(任意)sql 没有预期结果 (jdbcTemplate.execute():void)
/query
: 查询(for a 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
和returns:
[{"ID":1,"TITLE":"foo","SUBMISSION_DATE":"2021-11-17"},{"ID":2,"TITLE":"bar","SUBMISSION_DATE":"2021-11-17"}]
- Let me the possibility to connect to this hsqldb server remotely, for instance using the embedded Swing app contained into hsqldb.jar.
(远程需要测试,但是)从本地主机看是这样的:
.. 我们得到(所有)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;
}
,类似于 ,显示没有问题(像魅力一样工作)。
但是,添加此依赖项:
<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 中的某处....
Solution/Workaround:
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 移动到新的 class(es)(这还不错,只是为了“简洁”),否则我们会得到循环的 dependencies/unset 数据源。
我看到了这个 post :
我的目标是构建一个 Spring 启动应用
- 以服务器模式启动 HSQLDB,具有文件持久性(以便在我重新启动我的应用程序时取回它)
- 公开与此 hsqldb 实例通信的 public API
- 让我可以远程连接到这个 hsqldb 服务器,例如使用 hsqldb.jar 中包含的嵌入式 Swing 应用程序。
所以我尝试重现引用post的标记答案:
<?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.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.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[=14=](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.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 首先启动服务器,然后发挥它的魔力?
谢谢
这些都是非常“无条件的目标”,我 不 称其为“正确整合”,但你去吧:
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.Whosebug</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><!-- just for fun -->
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId><!-- TODO! -->
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
在 link, an additional @Component
annotation and some Properties loading 的友好帮助下,我们这样做了:
package com.Whosebug.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();
}
}
主要class/Config/Controller:
package com.Whosebug.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
我们得到:
- Start HSQLDB in server mode, with file persistence (to get it back when I restart my app)
看这里:
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)
- Expose a public API that communicates with this hsqldb instance:
/execute
:执行(任意)sql 没有预期结果 (jdbcTemplate.execute():void)/query
: 查询(for aList<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
和returns:
[{"ID":1,"TITLE":"foo","SUBMISSION_DATE":"2021-11-17"},{"ID":2,"TITLE":"bar","SUBMISSION_DATE":"2021-11-17"}]
- Let me the possibility to connect to this hsqldb server remotely, for instance using the embedded Swing app contained into hsqldb.jar.
(远程需要测试,但是)从本地主机看是这样的:
.. 我们得到(所有)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;
}
,类似于
但是,添加此依赖项:
<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 中的某处....
Solution/Workaround:
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 移动到新的 class(es)(这还不错,只是为了“简洁”),否则我们会得到循环的 dependencies/unset 数据源。