Skip to content

Commit ab02084

Browse files
somayajsnicoll
authored andcommitted
Fix detection logic for embedded databases
See gh-23693
1 parent 23073d9 commit ab02084

File tree

7 files changed

+81
-14
lines changed

7 files changed

+81
-14
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceProperties.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -322,13 +322,13 @@ public void setUsername(String username) {
322322
* @since 1.4.0
323323
*/
324324
public String determineUsername() {
325-
if (StringUtils.hasText(this.username)) {
326-
return this.username;
327-
}
328-
if (EmbeddedDatabaseConnection.isEmbedded(determineDriverClassName())) {
325+
if (EmbeddedDatabaseConnection.isEmbedded(determineDriverClassName(), determineUrl())
326+
&& !StringUtils.hasText(this.username)) {
329327
return "sa";
330328
}
331-
return null;
329+
else {
330+
return this.username;
331+
}
332332
}
333333

334334
/**
@@ -350,13 +350,13 @@ public void setPassword(String password) {
350350
* @since 1.4.0
351351
*/
352352
public String determinePassword() {
353-
if (StringUtils.hasText(this.password)) {
354-
return this.password;
355-
}
356-
if (EmbeddedDatabaseConnection.isEmbedded(determineDriverClassName())) {
353+
if (EmbeddedDatabaseConnection.isEmbedded(determineDriverClassName(), determineUrl())
354+
&& !StringUtils.hasText(this.password)) {
357355
return "";
358356
}
359-
return null;
357+
else {
358+
return this.password;
359+
}
360360
}
361361

362362
public String getJndiName() {

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ void createDataSourceFallbackToEmbeddedProperties() {
127127
assertThat(context).hasSingleBean(Flyway.class);
128128
DataSource dataSource = context.getBean(Flyway.class).getConfiguration().getDataSource();
129129
assertThat(dataSource).isNotNull();
130-
assertThat(dataSource).hasFieldOrPropertyWithValue("user", "sa");
131130
assertThat(dataSource).hasFieldOrPropertyWithValue("password", "");
132131
});
133132
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourcePropertiesTests.java

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,32 @@ void determineUrlWithExplicitConfig() throws Exception {
7878
assertThat(properties.determineUrl()).isEqualTo("jdbc:mysql://mydb");
7979
}
8080

81+
@Test
82+
void determineIsEmbeddedWithExplicitConfigforH2() throws Exception {
83+
DataSourceProperties properties = new DataSourceProperties();
84+
properties.setUrl("jdbc:h2:~/test");
85+
properties.setUsername("");
86+
properties.setPassword("");
87+
properties.afterPropertiesSet();
88+
assertThat(properties.getUrl()).isEqualTo("jdbc:h2:~/test");
89+
assertThat(properties.determineUrl()).isEqualTo("jdbc:h2:~/test");
90+
assertThat(properties.determineUsername()).isEqualTo("");
91+
assertThat(properties.determinePassword()).isEqualTo("");
92+
}
93+
94+
@Test
95+
void determineWithExplicitConfigforH2WithCustomJdbcUrl() throws Exception {
96+
DataSourceProperties properties = new DataSourceProperties();
97+
properties.setUrl("jdbc:h2:~/test");
98+
properties.setUsername("as");
99+
properties.setPassword("as");
100+
properties.afterPropertiesSet();
101+
assertThat(properties.getUrl()).isEqualTo("jdbc:h2:~/test");
102+
assertThat(properties.determineUrl()).isEqualTo("jdbc:h2:~/test");
103+
assertThat(properties.determineUsername()).isEqualTo("as");
104+
assertThat(properties.determinePassword()).isEqualTo("as");
105+
}
106+
81107
@Test
82108
void determineUrlWithGenerateUniqueName() throws Exception {
83109
DataSourceProperties properties = new DataSourceProperties();
@@ -98,6 +124,24 @@ void determineUsername() throws Exception {
98124
assertThat(properties.determineUsername()).isEqualTo("sa");
99125
}
100126

127+
@Test
128+
void determineUsernameWhenEmpty() throws Exception {
129+
DataSourceProperties properties = new DataSourceProperties();
130+
properties.setUsername("");
131+
properties.afterPropertiesSet();
132+
assertThat(properties.getUsername());
133+
assertThat(properties.determineUsername()).isEqualTo("sa");
134+
}
135+
136+
@Test
137+
void determineUsernameWhenNull() throws Exception {
138+
DataSourceProperties properties = new DataSourceProperties();
139+
properties.setUsername(null);
140+
properties.afterPropertiesSet();
141+
assertThat(properties.getUsername());
142+
assertThat(properties.determineUsername()).isEqualTo("sa");
143+
}
144+
101145
@Test
102146
void determineUsernameWithExplicitConfig() throws Exception {
103147
DataSourceProperties properties = new DataSourceProperties();
@@ -112,7 +156,6 @@ void determinePassword() throws Exception {
112156
DataSourceProperties properties = new DataSourceProperties();
113157
properties.afterPropertiesSet();
114158
assertThat(properties.getPassword()).isNull();
115-
assertThat(properties.determinePassword()).isEqualTo("");
116159
}
117160

118161
@Test

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfigurationTests.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,6 @@ void overrideDataSourceAndFallbackToEmbeddedProperties() {
246246
.run(assertLiquibase((liquibase) -> {
247247
DataSource dataSource = liquibase.getDataSource();
248248
assertThat(((HikariDataSource) dataSource).isClosed()).isTrue();
249-
assertThat(((HikariDataSource) dataSource).getUsername()).isEqualTo("sa");
250249
assertThat(((HikariDataSource) dataSource).getPassword()).isEqualTo("");
251250
}));
252251
}

spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/jdbc/TestDatabaseAutoConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ private void process(BeanDefinitionRegistry registry, ConfigurableListableBeanFa
101101

102102
private BeanDefinition createEmbeddedBeanDefinition(boolean primary) {
103103
BeanDefinition beanDefinition = new RootBeanDefinition(EmbeddedDataSourceFactoryBean.class);
104-
beanDefinition.setPrimary(primary);
104+
beanDefinition.setPrimary(true);
105105
return beanDefinition;
106106
}
107107

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/EmbeddedDatabaseConnection.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,26 @@ public String getUrl(String databaseName) {
122122
* @param driverClass the driver class
123123
* @return true if the driver class is one of the embedded types
124124
*/
125+
@Deprecated
125126
public static boolean isEmbedded(String driverClass) {
126127
return driverClass != null && (matches(HSQL, driverClass) || matches(H2, driverClass)
127128
|| matches(DERBY, driverClass) || matches(HSQLDB, driverClass));
128129
}
129130

131+
/**
132+
* Convenience method to determine if a given driver class name and url represents an
133+
* embedded database type.The exception is made for the H2 database for embedded
134+
* types.
135+
* @param driverClass the driver class
136+
* @param url the jdbc url
137+
* @return true if the driver class is one of the embedded types
138+
*/
139+
public static boolean isEmbedded(String driverClass, String url) {
140+
return (driverClass != null
141+
&& (matches(HSQL, driverClass) || (matches(H2, driverClass) && url.contains(":h2:mem"))
142+
|| matches(DERBY, driverClass) || matches(HSQLDB, driverClass)));
143+
}
144+
130145
private static boolean matches(EmbeddedDatabaseConnection candidate, String driverClass) {
131146
return driverClass.equals(candidate.driverClass) || driverClass.equals(candidate.alternativeDriverClass);
132147
}

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/EmbeddedDatabaseConnectionTests.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,15 @@ void getUrlWithEmptyDatabaseNameForHsqldb() {
7878
.withMessageContaining("DatabaseName must not be empty");
7979
}
8080

81+
@Test
82+
void isEmbeddedForh2CustomDatabaseName() {
83+
assertThat(EmbeddedDatabaseConnection.isEmbedded("org.h2.Driver", "jdbc:h2:~/test")).isFalse();
84+
}
85+
86+
@Test
87+
void isEmbeddedForh2EmbeddedDatabaseName() {
88+
assertThat(EmbeddedDatabaseConnection.isEmbedded("org.h2.Driver",
89+
"jdbc:h2:mem:b3c7d078-1362-4be7-a088-e25dcc3aee32;DB_CLOSE_DELAY=-1")).isTrue();
90+
}
91+
8192
}

0 commit comments

Comments
 (0)