Skip to content

Commit a8c778c

Browse files
authored
Use JdbcConnectionDetails to detect Dialect instead of Environment (#294)
* Use JdbcConnectionDetails to detect Dialect instead of Environment closes gh-286 * Address a case where ConnectionDetails is not generated * Clean up
1 parent d4e0878 commit a8c778c

File tree

3 files changed

+102
-30
lines changed

3 files changed

+102
-30
lines changed

doma-spring-boot-autoconfigure/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@
6161
<artifactId>h2</artifactId>
6262
<scope>test</scope>
6363
</dependency>
64+
<dependency>
65+
<groupId>org.postgresql</groupId>
66+
<artifactId>postgresql</artifactId>
67+
<scope>test</scope>
68+
</dependency>
6469
<dependency>
6570
<groupId>com.zaxxer</groupId>
6671
<artifactId>HikariCP</artifactId>

doma-spring-boot-autoconfigure/src/main/java/org/seasar/doma/boot/autoconfigure/DomaAutoConfiguration.java

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.seasar.doma.jdbc.dialect.StandardDialect;
4040
import org.seasar.doma.jdbc.statistic.DefaultStatisticManager;
4141
import org.seasar.doma.jdbc.statistic.StatisticManager;
42+
import org.springframework.beans.factory.BeanCreationException;
4243
import org.springframework.beans.factory.ObjectProvider;
4344
import org.springframework.beans.factory.annotation.Autowired;
4445
import org.springframework.beans.factory.annotation.Qualifier;
@@ -47,11 +48,11 @@
4748
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
4849
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
4950
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
51+
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
5052
import org.springframework.boot.context.properties.EnableConfigurationProperties;
5153
import org.springframework.boot.jdbc.DatabaseDriver;
5254
import org.springframework.context.annotation.Bean;
5355
import org.springframework.context.annotation.Configuration;
54-
import org.springframework.core.env.Environment;
5556
import org.springframework.core.io.ResourceLoader;
5657
import org.springframework.dao.support.PersistenceExceptionTranslator;
5758
import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
@@ -76,39 +77,41 @@ public class DomaAutoConfiguration {
7677

7778
@Bean
7879
@ConditionalOnMissingBean
79-
public Dialect dialect(Environment environment) {
80+
public Dialect dialect(ObjectProvider<JdbcConnectionDetails> connectionDetailsProvider) {
8081
DialectType dialectType = domaProperties.getDialect();
8182
if (dialectType != null) {
8283
return dialectType.create();
8384
}
84-
String url = environment.getProperty("spring.datasource.url");
85-
if (url != null) {
86-
DatabaseDriver databaseDriver = DatabaseDriver.fromJdbcUrl(url);
87-
switch (databaseDriver) {
88-
case DB2:
89-
return new Db2Dialect();
90-
case H2:
91-
return new H2Dialect();
92-
case HSQLDB:
93-
return new HsqldbDialect();
94-
case SQLSERVER:
95-
case JTDS:
96-
return new MssqlDialect();
97-
case MYSQL:
98-
return new MysqlDialect();
99-
case ORACLE:
100-
return new OracleDialect();
101-
case POSTGRESQL:
102-
return new PostgresDialect();
103-
case SQLITE:
104-
return new SqliteDialect();
105-
default:
106-
break;
107-
}
85+
JdbcConnectionDetails connectionDetails = connectionDetailsProvider.getIfAvailable();
86+
if (connectionDetails == null) {
87+
throw new BeanCreationException(
88+
"No connection details available. You will probably have to set 'doma.dialect' explicitly.");
89+
}
90+
DatabaseDriver databaseDriver = DatabaseDriver.fromJdbcUrl(connectionDetails.getJdbcUrl());
91+
switch (databaseDriver) {
92+
case DB2:
93+
return new Db2Dialect();
94+
case H2:
95+
return new H2Dialect();
96+
case HSQLDB:
97+
return new HsqldbDialect();
98+
case SQLSERVER:
99+
case JTDS:
100+
return new MssqlDialect();
101+
case MYSQL:
102+
return new MysqlDialect();
103+
case ORACLE:
104+
return new OracleDialect();
105+
case POSTGRESQL:
106+
return new PostgresDialect();
107+
case SQLITE:
108+
return new SqliteDialect();
109+
default:
110+
break;
108111
}
109112
if (logger.isWarnEnabled()) {
110113
logger.warn(
111-
"StandardDialect was selected because no explicit configuration and it is not possible to guess from 'spring.datasource.url property'");
114+
"StandardDialect was selected because no explicit configuration and it is not possible to guess from the connection details.");
112115
}
113116
return new StandardDialect();
114117
}

doma-spring-boot-autoconfigure/src/test/java/org/seasar/doma/boot/autoconfigure/DomaAutoConfigurationTest.java

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package org.seasar.doma.boot.autoconfigure;
22

3+
import static org.hamcrest.CoreMatchers.containsString;
34
import static org.hamcrest.CoreMatchers.instanceOf;
45
import static org.hamcrest.CoreMatchers.is;
56
import static org.hamcrest.CoreMatchers.notNullValue;
67
import static org.hamcrest.MatcherAssert.assertThat;
78
import static org.junit.jupiter.api.Assertions.assertEquals;
89
import static org.junit.jupiter.api.Assertions.assertFalse;
910
import static org.junit.jupiter.api.Assertions.assertNotNull;
11+
import static org.junit.jupiter.api.Assertions.assertThrows;
1012
import static org.junit.jupiter.api.Assertions.assertTrue;
1113
import static org.mockito.ArgumentMatchers.anyString;
1214
import static org.mockito.Mockito.mock;
@@ -49,15 +51,16 @@
4951
import org.seasar.doma.jdbc.criteria.NativeSql;
5052
import org.seasar.doma.jdbc.criteria.QueryDsl;
5153
import org.seasar.doma.jdbc.dialect.Dialect;
52-
import org.seasar.doma.jdbc.dialect.H2Dialect;
5354
import org.seasar.doma.jdbc.dialect.MysqlDialect;
5455
import org.seasar.doma.jdbc.dialect.PostgresDialect;
5556
import org.seasar.doma.jdbc.dialect.StandardDialect;
5657
import org.seasar.doma.jdbc.statistic.DefaultStatisticManager;
5758
import org.seasar.doma.jdbc.statistic.StatisticManager;
5859
import org.seasar.doma.message.Message;
60+
import org.springframework.beans.factory.BeanCreationException;
5961
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
6062
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
63+
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
6164
import org.springframework.context.ConfigurableApplicationContext;
6265
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
6366
import org.springframework.context.annotation.Bean;
@@ -69,6 +72,7 @@
6972
import org.springframework.dao.DataIntegrityViolationException;
7073
import org.springframework.dao.QueryTimeoutException;
7174
import org.springframework.dao.support.PersistenceExceptionTranslator;
75+
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
7276
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
7377

7478
public class DomaAutoConfigurationTest {
@@ -263,11 +267,71 @@ public void testDialectByDataSourceUrl() {
263267
MutablePropertySources sources = context.getEnvironment()
264268
.getPropertySources();
265269
sources.addFirst(new MapPropertySource("test",
266-
Collections.singletonMap("spring.datasource.url", "jdbc:h2:mem:example")));
270+
Map.of("spring.datasource.url", "jdbc:postgresql://localhost:1234/example",
271+
"doma.exception-translation-enabled",
272+
"false" /* prevent database connections */)));
267273
this.context.register(DomaAutoConfiguration.class, DataSourceAutoConfiguration.class);
268274
this.context.refresh();
269275
Dialect dialect = this.context.getBean(Dialect.class);
270-
assertThat(dialect, is(instanceOf(H2Dialect.class)));
276+
assertThat(dialect, is(instanceOf(PostgresDialect.class)));
277+
}
278+
279+
@Test
280+
public void testDialectByJdbConnectionDetails() {
281+
MutablePropertySources sources = context.getEnvironment()
282+
.getPropertySources();
283+
sources.addFirst(new MapPropertySource("test",
284+
Map.of("doma.exception-translation-enabled",
285+
"false"/* prevent database connections */)));
286+
this.context.register(DomaAutoConfiguration.class, DataSourceAutoConfiguration.class);
287+
this.context.registerBean(JdbcConnectionDetails.class, () -> new JdbcConnectionDetails() {
288+
@Override
289+
public String getUsername() {
290+
return "dummy";
291+
}
292+
293+
@Override
294+
public String getPassword() {
295+
return "dummy";
296+
}
297+
298+
@Override
299+
public String getJdbcUrl() {
300+
return "jdbc:postgresql://localhost:1234/example";
301+
}
302+
});
303+
this.context.refresh();
304+
Dialect dialect = this.context.getBean(Dialect.class);
305+
assertThat(dialect, is(instanceOf(PostgresDialect.class)));
306+
}
307+
308+
@Test
309+
public void testDialectMissingJdbConnectionDetails() {
310+
MutablePropertySources sources = context.getEnvironment()
311+
.getPropertySources();
312+
sources.addFirst(new MapPropertySource("test",
313+
Map.of("doma.exception-translation-enabled",
314+
"false"/* prevent database connections */)));
315+
this.context.register(DomaAutoConfiguration.class, DataSourceAutoConfiguration.class);
316+
this.context.registerBean(DataSource.class, SimpleDriverDataSource::new);
317+
BeanCreationException exception = assertThrows(BeanCreationException.class,
318+
() -> this.context.refresh());
319+
assertThat(exception.getMessage(), containsString(
320+
"No connection details available. You will probably have to set 'doma.dialect' explicitly."));
321+
}
322+
323+
@Test
324+
public void testDialectMissingJdbConnectionDetailsExplicitDialect() {
325+
MutablePropertySources sources = context.getEnvironment()
326+
.getPropertySources();
327+
sources.addFirst(new MapPropertySource("test",
328+
Map.of("doma.dialect", "POSTGRES", "doma.exception-translation-enabled",
329+
"false"/* prevent database connections */)));
330+
this.context.register(DomaAutoConfiguration.class, DataSourceAutoConfiguration.class);
331+
this.context.registerBean(DataSource.class, SimpleDriverDataSource::new);
332+
this.context.refresh();
333+
Dialect dialect = this.context.getBean(Dialect.class);
334+
assertThat(dialect, is(instanceOf(PostgresDialect.class)));
271335
}
272336

273337
@Test

0 commit comments

Comments
 (0)