我尝试使用Spring Boot 2.0.3连接到外部H2 DB,而我的配置是
spring:
datasource:
url: jdbc:h2:tcp://localhost:8082/mem:testdb
driverClassName: org.h2.Driver
username: sa
password:
但是,当我启动启动应用程序时,我遇到了JdbcSQLException。
org.h2.jdbc.JdbcSQLException: Connection is broken: "java.io.EOFException: localhost:8082" [90067-197]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:357) ~[h2-1.4.197.jar:1.4.197]
at org.h2.message.DbException.get(DbException.java:168) ~[h2-1.4.197.jar:1.4.197]
at org.h2.engine.SessionRemote.connectServer(SessionRemote.java:451) ~[h2-1.4.197.jar:1.4.197]
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:332) ~[h2-1.4.197.jar:1.4.197]
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:124) ~[h2-1.4.197.jar:1.4.197]
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:103) ~[h2-1.4.197.jar:1.4.197]
at org.h2.Driver.connect(Driver.java:69) ~[h2-1.4.197.jar:1.4.197]
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:117) ~[HikariCP-2.7.9.jar:na]
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:123) ~[HikariCP-2.7.9.jar:na]
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:365) ~[HikariCP-2.7.9.jar:na]
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:194) ~[HikariCP-2.7.9.jar:na]
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:460) [HikariCP-2.7.9.jar:na]
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:534) [HikariCP-2.7.9.jar:na]
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115) [HikariCP-2.7.9.jar:na]
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) [HikariCP-2.7.9.jar:na]
at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:151) [spring-jdbc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:115) [spring-jdbc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:78) [spring-jdbc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:319) [spring-jdbc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:356) [spring-jdbc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.boot.autoconfigure.orm.jpa.DatabaseLookup.getDatabase(DatabaseLookup.java:72) [spring-boot-autoconfigure-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.boot.autoconfigure.orm.jpa.JpaProperties.determineDatabase(JpaProperties.java:166) [spring-boot-autoconfigure-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.jpaVendorAdapter(JpaBaseConfiguration.java:111) [spring-boot-autoconfigure-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration$$EnhancerBySpringCGLIB$$6fb2f33f.CGLIB$jpaVendorAdapter$4(<generated>) [spring-boot-autoconfigure-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration$$EnhancerBySpringCGLIB$$6fb2f33f$$FastClassBySpringCGLIB$$25c4d08f.invoke(<generated>) [spring-boot-autoconfigure-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) [spring-core-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:361) [spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration$$EnhancerBySpringCGLIB$$6fb2f33f.jpaVendorAdapter(<generated>) [spring-boot-autoconfigure-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_161]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_161]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_161]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_161]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:582) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1256) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1105) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:503) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:251) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1065) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:818) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:724) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:474) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1256) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1105) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:503) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:251) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1065) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:818) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:724) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:474) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1256) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1105) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:503) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) [spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1089) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:859) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) ~[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395) ~[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) ~[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255) ~[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243) ~[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at com.community.CommunityApplication.main(CommunityApplication.java:19) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_161]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_161]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_161]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_161]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.0.3.RELEASE.jar:2.0.3.RELEASE]
Caused by: java.io.EOFException: null
at java.io.DataInputStream.readInt(DataInputStream.java:392) ~[na:1.8.0_161]
at org.h2.value.Transfer.readInt(Transfer.java:146) ~[h2-1.4.197.jar:1.4.197]
at org.h2.engine.SessionRemote.done(SessionRemote.java:616) ~[h2-1.4.197.jar:1.4.197]
at org.h2.engine.SessionRemote.initTransfer(SessionRemote.java:132) ~[h2-1.4.197.jar:1.4.197]
at org.h2.engine.SessionRemote.connectServer(SessionRemote.java:447) ~[h2-1.4.197.jar:1.4.197]
... 82 common frames omitted
我发现此异常在SessionRemote.connectServer上抛出(我标记了它所在的位置)
private void connectServer(ConnectionInfo ci) {
String name = ci.getName();
if (name.startsWith("//")) {
name = name.substring("//".length());
}
int idx = name.indexOf('/');
if (idx < 0) {
throw ci.getFormatException();
}
databaseName = name.substring(idx + 1);
String server = name.substring(0, idx);
traceSystem = new TraceSystem(null);
String traceLevelFile = ci.getProperty(
SetTypes.TRACE_LEVEL_FILE, null);
if (traceLevelFile != null) {
int level = Integer.parseInt(traceLevelFile);
String prefix = getFilePrefix(
SysProperties.CLIENT_TRACE_DIRECTORY);
try {
traceSystem.setLevelFile(level);
if (level > 0 && level < 4) {
String file = FileUtils.createTempFile(prefix,
Constants.SUFFIX_TRACE_FILE, false, false);
traceSystem.setFileName(file);
}
} catch (IOException e) {
throw DbException.convertIOException(e, prefix);
}
}
String traceLevelSystemOut = ci.getProperty(
SetTypes.TRACE_LEVEL_SYSTEM_OUT, null);
if (traceLevelSystemOut != null) {
int level = Integer.parseInt(traceLevelSystemOut);
traceSystem.setLevelSystemOut(level);
}
trace = traceSystem.getTrace(Trace.JDBC);
String serverList = null;
if (server.indexOf(',') >= 0) {
serverList = StringUtils.quoteStringSQL(server);
ci.setProperty("CLUSTER", Constants.CLUSTERING_ENABLED);
}
autoReconnect = ci.getProperty("AUTO_RECONNECT", false);
// AUTO_SERVER implies AUTO_RECONNECT
boolean autoServer = ci.getProperty("AUTO_SERVER", false);
if (autoServer && serverList != null) {
throw DbException
.getUnsupportedException("autoServer && serverList != null");
}
autoReconnect |= autoServer;
if (autoReconnect) {
String className = ci.getProperty("DATABASE_EVENT_LISTENER");
if (className != null) {
className = StringUtils.trim(className, true, true, "'");
try {
eventListener = (DatabaseEventListener) JdbcUtils
.loadUserClass(className).newInstance();
} catch (Throwable e) {
throw DbException.convert(e);
}
}
}
cipher = ci.getProperty("CIPHER");
if (cipher != null) {
fileEncryptionKey = MathUtils.secureRandomBytes(32);
}
String[] servers = StringUtils.arraySplit(server, ',', true);
int len = servers.length;
transferList.clear();
sessionId = StringUtils.convertBytesToHex(MathUtils.secureRandomBytes(32));
// TODO cluster: support more than 2 connections
boolean switchOffCluster = false;
try {
for (String s : servers) {
try {
Transfer trans = initTransfer(ci, databaseName, s);
transferList.add(trans);
} catch (IOException e) {
/***********************************************
* Here! *
***********************************************/
if (len == 1) {
throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, e, e + ": " + s);
}
switchOffCluster = true;
}
}
checkClosed();
if (switchOffCluster) {
switchOffCluster();
}
checkClusterDisableAutoCommit(serverList);
} catch (DbException e) {
traceSystem.close();
throw e;
}
}
发生这种情况是因为服务器的长度为1。
String[] servers = StringUtils.arraySplit(server, ',', true);
int len = servers.length;
因此,我在这样的端口后添加了逗号,以使服务器的长度为2。 而且有效。
spring:
datasource:
# url: jdbc:h2:tcp://localhost:8082/mem:testdb
url: jdbc:h2:tcp://localhost:8082,/mem:testdb
driverClassName: org.h2.Driver
username: sa
password:
但是我不确定这是避免这种情况并连接到外部H2 DB的正确方法。 (我也发现了与2.1.2版本相同的情况)
谢谢。
答案 0 :(得分:0)
尝试将DB_CLOSE_DELAY=-1
添加到URL:
url:jdbc:h2:tcp:// localhost:8082 / mem:testdb; DB_CLOSE_DELAY = -1
我怀疑H2正在关闭连接。
这来自此处的文档:http://www.h2database.com/html/features.html
要从另一个进程或另一个进程访问内存数据库 在计算机上,您需要以与 内存数据库已创建。然后其他过程需要 使用数据库URL,例如,通过TCP / IP或TLS访问数据库: jdbc:h2:tcp:// localhost / mem:db1。
默认情况下,关闭与数据库的最后一个连接会关闭 数据库。对于内存数据库,这意味着内容丢失。 要保持数据库打开状态,请在数据库URL上添加; DB_CLOSE_DELAY = -1。 保持内存数据库的内容与虚拟的一样长 机器还活着,请使用jdbc:h2:mem:test; DB_CLOSE_DELAY = -1。