#57 - Add support for R2DBC subclass exception translation.

We now use R2DBC's exception hierarchy to translate exceptions into Spring's DataAccessException hierarchy.

Original pull request: #97.
This commit is contained in:
Mark Paluch
2019-03-19 12:38:19 +01:00
committed by Jens Schauder
parent 9c6142f941
commit e161476d1c
7 changed files with 220 additions and 9 deletions

View File

@@ -27,8 +27,9 @@ import javax.sql.DataSource;
import org.junit.Before;
import org.junit.Test;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.r2dbc.testing.R2dbcIntegrationTestSupport;
@@ -125,7 +126,7 @@ public abstract class AbstractDatabaseClientIntegrationTests extends R2dbcIntegr
.fetch().rowsUpdated() //
.as(StepVerifier::create) //
.expectErrorSatisfies(exception -> assertThat(exception) //
.isInstanceOf(DuplicateKeyException.class) //
.isInstanceOf(DataIntegrityViolationException.class) //
.hasMessageContaining("execute; SQL [INSERT INTO legoset")) //
.verify();
}

View File

@@ -0,0 +1,114 @@
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.r2dbc.support;
import static org.assertj.core.api.Assertions.*;
import io.r2dbc.spi.R2dbcBadGrammarException;
import io.r2dbc.spi.R2dbcDataIntegrityViolationException;
import io.r2dbc.spi.R2dbcException;
import io.r2dbc.spi.R2dbcNonTransientResourceException;
import io.r2dbc.spi.R2dbcPermissionDeniedException;
import io.r2dbc.spi.R2dbcRollbackException;
import io.r2dbc.spi.R2dbcTimeoutException;
import io.r2dbc.spi.R2dbcTransientResourceException;
import org.junit.Test;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.PermissionDeniedDataAccessException;
import org.springframework.dao.QueryTimeoutException;
import org.springframework.dao.TransientDataAccessResourceException;
import org.springframework.data.r2dbc.BadSqlGrammarException;
import org.springframework.data.r2dbc.UncategorizedR2dbcException;
/**
* Unit tests for {@link R2dbcExceptionSubclassTranslator}.
*
* @author Mark Paluch
*/
public class R2dbcExceptionSubclassTranslatorUnitTests {
R2dbcExceptionSubclassTranslator translator = new R2dbcExceptionSubclassTranslator();
@Test // gh-57
public void shouldTranslateTransientResourceException() {
Exception exception = translator.translate("", "", new R2dbcTransientResourceException());
assertThat(exception).isInstanceOf(TransientDataAccessResourceException.class);
}
@Test // gh-57
public void shouldTranslateRollbackException() {
Exception exception = translator.translate("", "", new R2dbcRollbackException());
assertThat(exception).isInstanceOf(ConcurrencyFailureException.class);
}
@Test // gh-57
public void shouldTranslateTimeoutException() {
Exception exception = translator.translate("", "", new R2dbcTimeoutException());
assertThat(exception).isInstanceOf(QueryTimeoutException.class);
}
@Test // gh-57
public void shouldNotTranslateUnknownExceptions() {
Exception exception = translator.translate("", "", new MyTransientExceptions());
assertThat(exception).isInstanceOf(UncategorizedR2dbcException.class);
}
@Test // gh-57
public void shouldTranslateNonTransientResourceException() {
Exception exception = translator.translate("", "", new R2dbcNonTransientResourceException());
assertThat(exception).isInstanceOf(DataAccessResourceFailureException.class);
}
@Test // gh-57
public void shouldTranslateIntegrityViolationException() {
Exception exception = translator.translate("", "", new R2dbcDataIntegrityViolationException());
assertThat(exception).isInstanceOf(DataIntegrityViolationException.class);
}
@Test // gh-57
public void shouldTranslatePermissionDeniedException() {
Exception exception = translator.translate("", "", new R2dbcPermissionDeniedException());
assertThat(exception).isInstanceOf(PermissionDeniedDataAccessException.class);
}
@Test // gh-57
public void shouldTranslateBadSqlGrammarException() {
Exception exception = translator.translate("", "", new R2dbcBadGrammarException());
assertThat(exception).isInstanceOf(BadSqlGrammarException.class);
}
private static class MyTransientExceptions extends R2dbcException {}
}