diff --git a/doma-spring-boot-autoconfigure/src/main/java/org/seasar/doma/boot/autoconfigure/DomaAutoConfiguration.java b/doma-spring-boot-autoconfigure/src/main/java/org/seasar/doma/boot/autoconfigure/DomaAutoConfiguration.java index b881d265..f4e206a9 100644 --- a/doma-spring-boot-autoconfigure/src/main/java/org/seasar/doma/boot/autoconfigure/DomaAutoConfiguration.java +++ b/doma-spring-boot-autoconfigure/src/main/java/org/seasar/doma/boot/autoconfigure/DomaAutoConfiguration.java @@ -30,6 +30,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.dao.support.PersistenceExceptionTranslator; +import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator; import javax.sql.DataSource; @@ -40,6 +41,7 @@ * Auto-configuration} for Doma. * * @author Toshiaki Maki + * @author Kazuki Shimizu */ @Configuration @ConditionalOnClass(Config.class) @@ -57,8 +59,8 @@ public Dialect dialect() { @Bean @ConditionalOnProperty(prefix = DomaProperties.DOMA_PREFIX, name = "exception-translation-enabled", matchIfMissing = true) - public PersistenceExceptionTranslator exceptionTranslator() { - return new DomaPersistenceExceptionTranslator(); + public PersistenceExceptionTranslator exceptionTranslator(Config config) { + return new DomaPersistenceExceptionTranslator(new SQLErrorCodeSQLExceptionTranslator(config.getDataSource())); } @Bean diff --git a/doma-spring-boot-autoconfigure/src/main/java/org/seasar/doma/boot/autoconfigure/DomaPersistenceExceptionTranslator.java b/doma-spring-boot-autoconfigure/src/main/java/org/seasar/doma/boot/autoconfigure/DomaPersistenceExceptionTranslator.java index c95713ab..07e2ce36 100644 --- a/doma-spring-boot-autoconfigure/src/main/java/org/seasar/doma/boot/autoconfigure/DomaPersistenceExceptionTranslator.java +++ b/doma-spring-boot-autoconfigure/src/main/java/org/seasar/doma/boot/autoconfigure/DomaPersistenceExceptionTranslator.java @@ -20,15 +20,20 @@ import org.seasar.doma.jdbc.*; import org.springframework.dao.*; import org.springframework.dao.support.PersistenceExceptionTranslator; -import org.springframework.jdbc.support.SQLExceptionSubclassTranslator; import org.springframework.jdbc.support.SQLExceptionTranslator; /** * Converts Doma's {@link JdbcException} into Spring's {@link DataAccessException}. * @author Toshiaki Maki + * @author Kazuki Shimizu */ public class DomaPersistenceExceptionTranslator implements PersistenceExceptionTranslator { - private final SQLExceptionTranslator translator = new SQLExceptionSubclassTranslator(); + + private final SQLExceptionTranslator translator; + + public DomaPersistenceExceptionTranslator(SQLExceptionTranslator sqlExceptionTranslator) { + this.translator = sqlExceptionTranslator; + } @Override public DataAccessException translateExceptionIfPossible(RuntimeException ex) { diff --git a/doma-spring-boot-autoconfigure/src/test/java/org/seasar/doma/boot/autoconfigure/DomaAutoConfigurationTest.java b/doma-spring-boot-autoconfigure/src/test/java/org/seasar/doma/boot/autoconfigure/DomaAutoConfigurationTest.java index 2690a79d..ebd9b75c 100644 --- a/doma-spring-boot-autoconfigure/src/test/java/org/seasar/doma/boot/autoconfigure/DomaAutoConfigurationTest.java +++ b/doma-spring-boot-autoconfigure/src/test/java/org/seasar/doma/boot/autoconfigure/DomaAutoConfigurationTest.java @@ -23,14 +23,23 @@ import org.seasar.doma.jdbc.dialect.MysqlDialect; import org.seasar.doma.jdbc.dialect.PostgresDialect; import org.seasar.doma.jdbc.dialect.StandardDialect; +import org.seasar.doma.message.Message; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.dao.CannotAcquireLockException; +import org.springframework.dao.DataAccessException; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.dao.QueryTimeoutException; +import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; import javax.sql.DataSource; +import java.sql.SQLException; +import java.sql.SQLTimeoutException; + import static org.junit.Assert.*; import static org.hamcrest.CoreMatchers.*; @@ -56,6 +65,8 @@ public void testAutoRegisteredConfig() { is(instanceOf(GreedyCacheSqlFileRepository.class))); assertThat(config.getNaming(), is(Naming.DEFAULT)); assertThat(config.getJdbcLogger(), is(instanceOf(UtilLoggingJdbcLogger.class))); + PersistenceExceptionTranslator translator = this.context.getBean(PersistenceExceptionTranslator.class); + assertThat(translator,is(instanceOf(DomaPersistenceExceptionTranslator.class))); } @Test @@ -72,6 +83,8 @@ public void testConfigWithDomaConfigBuilder() { is(instanceOf(NoCacheSqlFileRepository.class))); assertThat(config.getNaming(), is(Naming.SNAKE_UPPER_CASE)); assertThat(config.getJdbcLogger(), is(instanceOf(UtilLoggingJdbcLogger.class))); + PersistenceExceptionTranslator translator = this.context.getBean(PersistenceExceptionTranslator.class); + assertThat(translator,is(instanceOf(DomaPersistenceExceptionTranslator.class))); } @Test @@ -88,6 +101,34 @@ public void testConfigWithConfig() { is(instanceOf(NoCacheSqlFileRepository.class))); assertThat(config.getNaming(), is(Naming.SNAKE_LOWER_CASE)); assertThat(config.getJdbcLogger(), is(instanceOf(UtilLoggingJdbcLogger.class))); + PersistenceExceptionTranslator translator = this.context.getBean(PersistenceExceptionTranslator.class); + assertThat(translator,is(instanceOf(DomaPersistenceExceptionTranslator.class))); + } + + @Test + public void testSQLExceptionTranslator() { + this.context.register(DomaAutoConfiguration.class, + DataSourceAutoConfiguration.class); + this.context.refresh(); + PersistenceExceptionTranslator translator = this.context.getBean(PersistenceExceptionTranslator.class); + { + // Translated by SQLErrorCodeSQLExceptionTranslator + DataAccessException dataAccessException = translator.translateExceptionIfPossible( + new JdbcException(Message.DOMA2008, new SQLException("Acquire Lock on H2", "SqlState", 50200, null))); + assertThat(dataAccessException, is(instanceOf(CannotAcquireLockException.class))); + } + { + // Translated by SQLExceptionSubclassTranslator(fallback) + DataAccessException dataAccessException = translator.translateExceptionIfPossible( + new JdbcException(Message.DOMA2008, new SQLTimeoutException("Timeout", "SqlState", -1, null))); + assertThat(dataAccessException, is(instanceOf(QueryTimeoutException.class))); + } + { + // Translated by SQLStateSQLExceptionTranslator (fallback) + DataAccessException dataAccessException = translator.translateExceptionIfPossible( + new JdbcException(Message.DOMA2008, new SQLException("With check violation", "44", -1, null))); + assertThat(dataAccessException, is(instanceOf(DataIntegrityViolationException.class))); + } } @After