Skip to content

Instantly share code, notes, and snippets.

@mp911de
Created January 9, 2019 10:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mp911de/617ea7274ca984830d726bce552fc10f to your computer and use it in GitHub Desktop.
Save mp911de/617ea7274ca984830d726bce552fc10f to your computer and use it in GitHub Desktop.
/*
* 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
*
* http://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.repository;
import io.r2dbc.spi.ConnectionFactory;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import java.util.Map;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.FilterType;
import org.springframework.data.annotation.Id;
import org.springframework.data.r2dbc.config.AbstractR2dbcConfiguration;
import org.springframework.data.r2dbc.function.ReactiveDataAccessStrategy;
import org.springframework.data.r2dbc.function.TransactionalDatabaseClient;
import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories;
import org.springframework.data.r2dbc.support.R2dbcExceptionTranslator;
import org.springframework.data.r2dbc.testing.ExternalDatabase;
import org.springframework.data.r2dbc.testing.PostgresTestSupport;
import org.springframework.data.r2dbc.testing.R2dbcIntegrationTestSupport;
import org.springframework.data.relational.core.mapping.Table;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author Mark Paluch
*/
@RunWith(SpringRunner.class)
@ContextConfiguration
public class Repro extends R2dbcIntegrationTestSupport {
public static String CREATE_TABLE_LEGOSET_WITH_ID_GENERATION = "CREATE TABLE legoset (\n" //
+ " id serial CONSTRAINT id PRIMARY KEY,\n" //
+ " name varchar(255) NOT NULL,\n" //
+ " manual integer NULL\n" //
+ ");";
@ClassRule public static final ExternalDatabase database = PostgresTestSupport.database();
@Autowired LegoSetRepository legoSetRepository;
@Autowired TransactionalDatabaseClient client;
@EnableR2dbcRepositories(databaseClientRef = "transactionalDatabaseClient", considerNestedRepositories = true,
includeFilters = @Filter(value = LegoSetRepository.class, type = FilterType.ASSIGNABLE_TYPE))
static class MyConfig extends AbstractR2dbcConfiguration {
@Bean
@Override
public ConnectionFactory connectionFactory() {
return PostgresTestSupport.createConnectionFactory(database);
}
@Bean
public TransactionalDatabaseClient transactionalDatabaseClient(ReactiveDataAccessStrategy dataAccessStrategy,
R2dbcExceptionTranslator exceptionTranslator) {
return TransactionalDatabaseClient.builder() //
.connectionFactory(connectionFactory()) //
.dataAccessStrategy(dataAccessStrategy) //
.exceptionTranslator(exceptionTranslator) //
.build();
}
}
@Before
public void before() {
client.execute().sql("DROP TABLE IF EXISTS legoset;").then() //
.doOnSuccessOrError((aVoid, throwable) -> {}) //
.as(StepVerifier::create) //
.verifyComplete();
client.execute().sql(CREATE_TABLE_LEGOSET_WITH_ID_GENERATION).then() //
.as(StepVerifier::create) //
.verifyComplete();
}
@Test
public void reproducer() {
LegoSet legoSet1 = new LegoSet(null, "SCHAUFELRADBAGGER", 12);
Flux<Map<String, Object>> transactional = client.inTransaction(db -> {
return legoSetRepository.save(legoSet1) //
.then(Mono.error(new MyException()));
});
transactional.as(StepVerifier::create) //
.expectError(MyException.class) //
.verify();
legoSetRepository.count() //
.as(StepVerifier::create) //
.expectNext(0L) //
.verifyComplete();
}
interface LegoSetRepository extends ReactiveCrudRepository<LegoSet, Integer> {}
@Data
@Table("legoset")
@AllArgsConstructor
@NoArgsConstructor
static class LegoSet {
@Id Integer id;
String name;
Integer manual;
}
static class MyException extends RuntimeException {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment