我遇到的问题是Springboot版本的自动配置:1.5.9.RELEASE似乎无效。
注意,如果定义一个返回DataSource bean的bean,我大概可以解决当前的问题。
DataSource bean可能看起来非常类似于: 以下代码段中的示例: https://www.atomikos.com/Documentation/ConfiguringPostgreSQL
我将我的application.properties配置切换为停止使用Spring Boot使用的默认H2数据库,并将其切换为postgres。
下一页中显示的配置片段: https://dzone.com/articles/configuring-spring-boot-for-postgresql
肯定不起作用。 这是我的配置:
spring.datasource.url=jdbc:postgresql://localhost:5432/dummydb
spring.datasource.username=DUMMYDB
spring.datasource.password=DUMMYDB
spring.jpa.hibernate.ddl-auto=create-drop
这不起作用,为什么? 显然是出于非常简单的原因。 用户名和密码肯定是有用的,并且在连接工厂尝试为数据库建立连接时会被转移。 在配置数据源时,URL属性没有用。
让我首先为您提供最终的堆栈跟踪:
Caused by: org.postgresql.util.PSQLException: FATAL: database "null" does not exist
at org.postgresql.core.v3.ConnectionFactoryImpl.readStartupMessages(ConnectionFactoryImpl.java:469) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:112) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:66) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.jdbc2.AbstractJdbc2Connection.<init>(AbstractJdbc2Connection.java:125) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.jdbc3.AbstractJdbc3Connection.<init>(AbstractJdbc3Connection.java:30) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.jdbc3g.AbstractJdbc3gConnection.<init>(AbstractJdbc3gConnection.java:22) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.jdbc4.AbstractJdbc4Connection.<init>(AbstractJdbc4Connection.java:30) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.jdbc4.Jdbc4Connection.<init>(Jdbc4Connection.java:24) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.Driver.makeConnection(Driver.java:393) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.Driver.connect(Driver.java:267) ~[postgresql-9.1-901.jdbc4.jar:na]
at java.sql.DriverManager.getConnection(DriverManager.java:664) ~[na:1.8.0_112]
at java.sql.DriverManager.getConnection(DriverManager.java:247) ~[na:1.8.0_112]
at org.postgresql.ds.common.BaseDataSource.getConnection(BaseDataSource.java:91) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.xa.PGXADataSource.getXAConnection(PGXADataSource.java:47) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.xa.PGXADataSource.getXAConnection(PGXADataSource.java:32) ~[postgresql-9.1-901.jdbc4.jar:na]
at com.atomikos.jdbc.AtomikosXAConnectionFactory.createPooledConnection(AtomikosXAConnectionFactory.java:60) ~[transactions-jdbc-3.9.3.jar:na]
... 44 common frames omitted
之所以不起作用,是因为postgres基本数据源根本不关心通过URL进行配置。 而是希望通过传递的setter进行配置: databaseName,端口等... 请看以下课程:
org.postgresql.ds.common.BaseDataSource
此类提供了多个设置器。用于用户名,用于密码等。 但是,URL没有设置器。组成URL的各个元素(例如数据库名称)需要进入专用字段。
因此,该类提供的是此getURL()方法,该方法将重新调整datbase为null的奇怪URL。 这是该方法的代码段。
/**
* Generates a DriverManager URL from the other properties supplied.
*/
private String getUrl()
{
StringBuffer sb = new StringBuffer(100);
sb.append("jdbc:postgresql://");
sb.append(serverName);
if (portNumber != 0) {
sb.append(":").append(portNumber);
}
sb.append("/").append(databaseName);
sb.append("?loginTimeout=").append(loginTimeout);
sb.append("&socketTimeout=").append(socketTimeout);
sb.append("&prepareThreshold=").append(prepareThreshold);
sb.append("&unknownLength=").append(unknownLength);
sb.append("&loglevel=").append(logLevel);
if (protocolVersion != 0) {
sb.append("&protocolVersion=").append(protocolVersion);
}
if (ssl) {
sb.append("&ssl=true");
if (sslfactory != null) {
sb.append("&sslfactory=").append(sslfactory);
}
}
sb.append("&tcpkeepalive=").append(tcpKeepAlive);
if (compatible != null) {
sb.append("&compatible="+compatible);
}
if (applicationName != null) {
sb.append("&ApplicationName=");
sb.append(applicationName);
}
return sb.toString();
}
那么,对我来说,问题是。 好的...如果不希望通过URL配置postgres数据源,而是希望通过各种不同的设置器进行配置,也许我可以通过在application.properties文件字段中添加诸如以下内容来获得成功:
#spring.datasource.databaseName=dummydb
不,事实证明这似乎毫无用处。
经过一些调试,我设法找到了这个春季启动自动配置类:
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration
上面的类非常有趣,因为它位于原子JTA事务子系统的配置路径上。 IT将设置数据源:
org.postgresql.xa.PGXADataSource
但是唯一的问题是此自动配置器仅关心application.properties文件中的三个属性。 参见下面的代码段:
private void bindXaProperties(XADataSource target, DataSourceProperties properties) {
MutablePropertyValues values = new MutablePropertyValues();
values.add("user", this.properties.determineUsername());
values.add("password", this.properties.determinePassword());
values.add("url", this.properties.determineUrl());
values.addPropertyValues(properties.getXa().getProperties());
new RelaxedDataBinder(target).withAlias("user", "username").bind(values);
}
如您所见,我似乎“被烘烤”。 自动配置器没有任何其他可能相关的数据源属性的概念。 至少我感到惊讶。 我期待某种不会有任何东西的类,例如用户名和密码之类的属性的硬编码子集。 我期望某种代码会琐碎地循环所有applicaton.properties并寻找其键将以以下内容开头的任何属性:
spring.datasource.whatever
并在数据源类上调用datasource.setWhat 。
似乎并非如此。
所以我确定我一定在弄乱一些东西。 我不敢相信springboot不能在不强迫开发人员创建自己的数据源bean的情况下配置postgres数据库。 Postgress太主流了...
所以我想知道是否有人可以帮助我弄清楚如何正确配置application.properties文件,以确保确实可以使用springboot连接到postgres。
同时,我将通过编程创建类似以下的类来查看是否能解决此问题:
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(DataSourceProperties.class)
@ConditionalOnClass({ DataSource.class, TransactionManager.class,
EmbeddedDatabaseType.class })
@ConditionalOnBean(XADataSourceWrapper.class)
@ConditionalOnMissingBean(DataSource.class)
public class XADataSourceAutoConfiguration implements BeanClassLoaderAware {
但是在我的情况下,该类将知道如何以编程方式构建具有所有必需属性的postgres数据源以进行连接。
非常感谢您的帮助。