Do not configure a ReactiveNeo4jTransactionManager
The current arrangement with Neo4j does not allow us to know for sure that the user intends to use `@Transactional` for reactive or imperative operations. The main reason for that is that the only trigger for the reactive auto-configuration is the presence of reactor on the classpath given that the Neo4j driver ships with both styles in the same jar. And reactor can be on the classpath for a number of reasons that are unrelated to imperative access (typically `WebClient`). This commits removes the auto-configuration of the ReactiveNeo4jAutoConfiguration and makes sure that if the user defines one, the regular `PlatformTransactionManager` backs off. This is a temporarily situation until we can provide a better signal that the user intends to primarily use imperative repositories. Closes gh-22940
This commit is contained in:
@@ -47,6 +47,7 @@ import org.springframework.data.neo4j.core.schema.Node;
|
||||
import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager;
|
||||
import org.springframework.data.neo4j.repository.config.Neo4jRepositoryConfigurationExtension;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionManager;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data Neo4j.
|
||||
@@ -106,7 +107,7 @@ public class Neo4jDataAutoConfiguration {
|
||||
}
|
||||
|
||||
@Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_TRANSACTION_MANAGER_BEAN_NAME)
|
||||
@ConditionalOnMissingBean(PlatformTransactionManager.class)
|
||||
@ConditionalOnMissingBean(TransactionManager.class)
|
||||
public Neo4jTransactionManager transactionManager(Driver driver, DatabaseSelectionProvider databaseNameProvider,
|
||||
ObjectProvider<TransactionManagerCustomizers> optionalCustomizers) {
|
||||
Neo4jTransactionManager transactionManager = new Neo4jTransactionManager(driver, databaseNameProvider);
|
||||
|
||||
@@ -33,7 +33,6 @@ import org.springframework.data.neo4j.core.ReactiveNeo4jClient;
|
||||
import org.springframework.data.neo4j.core.ReactiveNeo4jOperations;
|
||||
import org.springframework.data.neo4j.core.ReactiveNeo4jTemplate;
|
||||
import org.springframework.data.neo4j.core.mapping.Neo4jMappingContext;
|
||||
import org.springframework.data.neo4j.core.transaction.ReactiveNeo4jTransactionManager;
|
||||
import org.springframework.data.neo4j.repository.config.ReactiveNeo4jRepositoryConfigurationExtension;
|
||||
import org.springframework.transaction.ReactiveTransactionManager;
|
||||
|
||||
@@ -46,8 +45,7 @@ import org.springframework.transaction.ReactiveTransactionManager;
|
||||
* @since 2.4.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ Driver.class, ReactiveNeo4jTransactionManager.class, ReactiveTransactionManager.class,
|
||||
Flux.class })
|
||||
@ConditionalOnClass({ Driver.class, ReactiveNeo4jTemplate.class, ReactiveTransactionManager.class, Flux.class })
|
||||
@ConditionalOnBean(Driver.class)
|
||||
@AutoConfigureAfter(Neo4jDataAutoConfiguration.class)
|
||||
@Import(Neo4jDefaultReactiveCallbacksRegistrar.class)
|
||||
@@ -74,11 +72,4 @@ public class Neo4jReactiveDataAutoConfiguration {
|
||||
return new ReactiveNeo4jTemplate(neo4jClient, neo4jMappingContext, databaseNameProvider);
|
||||
}
|
||||
|
||||
@Bean(ReactiveNeo4jRepositoryConfigurationExtension.DEFAULT_TRANSACTION_MANAGER_BEAN_NAME)
|
||||
@ConditionalOnMissingBean(ReactiveTransactionManager.class)
|
||||
public ReactiveTransactionManager reactiveTransactionManager(Driver driver,
|
||||
ReactiveDatabaseSelectionProvider databaseNameProvider) {
|
||||
return new ReactiveNeo4jTransactionManager(driver, databaseNameProvider);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ import org.springframework.data.neo4j.core.Neo4jTemplate;
|
||||
import org.springframework.data.neo4j.core.convert.Neo4jConversions;
|
||||
import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.ReactiveTransactionManager;
|
||||
import org.springframework.transaction.TransactionManager;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -119,6 +121,13 @@ class Neo4jDataAutoConfigurationTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBackoffIfReactiveTransactionManagerIsSet() {
|
||||
this.contextRunner.withBean(ReactiveTransactionManager.class, () -> mock(ReactiveTransactionManager.class))
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(Neo4jTransactionManager.class)
|
||||
.hasSingleBean(TransactionManager.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReuseExistingTransactionManager() {
|
||||
this.contextRunner
|
||||
|
||||
@@ -30,8 +30,8 @@ import org.springframework.data.neo4j.core.ReactiveDatabaseSelectionProvider;
|
||||
import org.springframework.data.neo4j.core.ReactiveNeo4jClient;
|
||||
import org.springframework.data.neo4j.core.ReactiveNeo4jOperations;
|
||||
import org.springframework.data.neo4j.core.ReactiveNeo4jTemplate;
|
||||
import org.springframework.data.neo4j.core.transaction.ReactiveNeo4jTransactionManager;
|
||||
import org.springframework.transaction.ReactiveTransactionManager;
|
||||
import org.springframework.transaction.TransactionManager;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -113,23 +113,12 @@ class Neo4jReactiveDataAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldProvideReactiveTransactionManager() {
|
||||
this.contextRunner.withUserConfiguration(CustomReactiveDatabaseSelectionProviderConfiguration.class)
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(ReactiveNeo4jTransactionManager.class);
|
||||
assertThat(context.getBean(ReactiveNeo4jTransactionManager.class))
|
||||
.extracting("databaseSelectionProvider")
|
||||
.isSameAs(context.getBean(ReactiveDatabaseSelectionProvider.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReuseExistingReactiveTransactionManager() {
|
||||
void shouldUseExistingReactiveTransactionManager() {
|
||||
this.contextRunner
|
||||
.withBean("myCustomReactiveTransactionManager", ReactiveTransactionManager.class,
|
||||
() -> mock(ReactiveTransactionManager.class))
|
||||
.run((context) -> assertThat(context).hasSingleBean(ReactiveTransactionManager.class)
|
||||
.hasBean("myCustomReactiveTransactionManager"));
|
||||
.hasSingleBean(TransactionManager.class));
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.springframework.boot.autoconfigure.data.neo4j.country.CountryReposito
|
||||
import org.springframework.boot.autoconfigure.data.neo4j.country.ReactiveCountryRepository;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.neo4j.core.transaction.ReactiveNeo4jTransactionManager;
|
||||
import org.springframework.data.neo4j.core.ReactiveNeo4jTemplate;
|
||||
import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository;
|
||||
import org.springframework.data.neo4j.repository.config.EnableReactiveNeo4jRepositories;
|
||||
|
||||
@@ -57,7 +57,7 @@ public class Neo4jReactiveRepositoriesAutoConfigurationTests {
|
||||
@Test
|
||||
void configurationWithNoRepositories() {
|
||||
this.contextRunner.withUserConfiguration(EmptyConfiguration.class).run((context) -> assertThat(context)
|
||||
.hasSingleBean(ReactiveNeo4jTransactionManager.class).doesNotHaveBean(ReactiveNeo4jRepository.class));
|
||||
.hasSingleBean(ReactiveNeo4jTemplate.class).doesNotHaveBean(ReactiveNeo4jRepository.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -70,7 +70,7 @@ public class Neo4jReactiveRepositoriesAutoConfigurationTests {
|
||||
@Test
|
||||
void autoConfigurationShouldNotKickInEvenIfManualConfigDidNotCreateAnyRepositories() {
|
||||
this.contextRunner.withUserConfiguration(SortOfInvalidCustomConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(ReactiveNeo4jTransactionManager.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(ReactiveNeo4jTemplate.class)
|
||||
.doesNotHaveBean(ReactiveNeo4jRepository.class));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user