From b6467ed826818db5d18061496768db3f6758c916 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 12 Feb 2024 14:10:03 +0000 Subject: [PATCH] Adapt to Spring Data Neo4j now requiring a transaction manager See gh-39493 --- .../neo4j/Neo4jDataAutoConfiguration.java | 30 +---------- .../Neo4jReactiveDataAutoConfiguration.java | 10 +++- .../Neo4jRepositoriesAutoConfiguration.java | 3 ++ .../Neo4jTransactionManagerConfiguration.java | 48 +++++++++++++++++ ...jTransactionalComponentsConfiguration.java | 54 +++++++++++++++++++ 5 files changed, 116 insertions(+), 29 deletions(-) create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jTransactionManagerConfiguration.java create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jTransactionalComponentsConfiguration.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java index 38cad56487c..1970e544972 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java @@ -20,7 +20,6 @@ import java.util.Set; import org.neo4j.driver.Driver; -import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -30,23 +29,18 @@ import org.springframework.boot.autoconfigure.domain.EntityScanner; import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration; import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizationAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; import org.springframework.data.neo4j.aot.Neo4jManagedTypes; import org.springframework.data.neo4j.core.DatabaseSelectionProvider; -import org.springframework.data.neo4j.core.Neo4jClient; -import org.springframework.data.neo4j.core.Neo4jOperations; -import org.springframework.data.neo4j.core.Neo4jTemplate; import org.springframework.data.neo4j.core.convert.Neo4jConversions; import org.springframework.data.neo4j.core.mapping.Neo4jMappingContext; import org.springframework.data.neo4j.core.schema.Node; import org.springframework.data.neo4j.core.schema.RelationshipProperties; 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. @@ -64,6 +58,7 @@ import org.springframework.transaction.TransactionManager; @ConditionalOnClass({ Driver.class, Neo4jTransactionManager.class, PlatformTransactionManager.class }) @EnableConfigurationProperties(Neo4jDataProperties.class) @ConditionalOnBean(Driver.class) +@Import({ Neo4jTransactionManagerConfiguration.class, Neo4jTransactionalComponentsConfiguration.class }) public class Neo4jDataAutoConfiguration { @Bean @@ -96,25 +91,4 @@ public class Neo4jDataAutoConfiguration { : DatabaseSelectionProvider.getDefaultSelectionProvider(); } - @Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_CLIENT_BEAN_NAME) - @ConditionalOnMissingBean - public Neo4jClient neo4jClient(Driver driver, DatabaseSelectionProvider databaseNameProvider) { - return Neo4jClient.create(driver, databaseNameProvider); - } - - @Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_TEMPLATE_BEAN_NAME) - @ConditionalOnMissingBean(Neo4jOperations.class) - public Neo4jTemplate neo4jTemplate(Neo4jClient neo4jClient, Neo4jMappingContext neo4jMappingContext) { - return new Neo4jTemplate(neo4jClient, neo4jMappingContext); - } - - @Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_TRANSACTION_MANAGER_BEAN_NAME) - @ConditionalOnMissingBean(TransactionManager.class) - public Neo4jTransactionManager transactionManager(Driver driver, DatabaseSelectionProvider databaseNameProvider, - ObjectProvider optionalCustomizers) { - Neo4jTransactionManager transactionManager = new Neo4jTransactionManager(driver, databaseNameProvider); - optionalCustomizers.ifAvailable((customizer) -> customizer.customize((TransactionManager) transactionManager)); - return transactionManager; - } - } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataAutoConfiguration.java index 94fa7836d31..b3c4752c0fa 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2024 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. @@ -30,6 +30,7 @@ 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; @@ -68,4 +69,11 @@ public class Neo4jReactiveDataAutoConfiguration { return new ReactiveNeo4jTemplate(neo4jClient, neo4jMappingContext); } + @Bean(ReactiveNeo4jRepositoryConfigurationExtension.DEFAULT_TRANSACTION_MANAGER_BEAN_NAME) + @ConditionalOnMissingBean(ReactiveTransactionManager.class) + ReactiveNeo4jTransactionManager rectiveNeo4jTransactionManager(Driver driver, + ReactiveDatabaseSelectionProvider databaseNameProvider) { + return new ReactiveNeo4jTransactionManager(driver, databaseNameProvider); + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfiguration.java index 05f2c7729e1..321407c2c6f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfiguration.java @@ -20,11 +20,13 @@ import org.neo4j.driver.Driver; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.data.ConditionalOnRepositoryType; import org.springframework.boot.autoconfigure.data.RepositoryType; import org.springframework.context.annotation.Import; +import org.springframework.data.neo4j.core.Neo4jTemplate; import org.springframework.data.neo4j.repository.Neo4jRepository; import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; import org.springframework.data.neo4j.repository.config.Neo4jRepositoryConfigurationExtension; @@ -52,6 +54,7 @@ import org.springframework.data.neo4j.repository.support.Neo4jRepositoryFactoryB @AutoConfiguration(after = Neo4jDataAutoConfiguration.class) @ConditionalOnClass({ Driver.class, Neo4jRepository.class }) @ConditionalOnMissingBean({ Neo4jRepositoryFactoryBean.class, Neo4jRepositoryConfigurationExtension.class }) +@ConditionalOnBean(Neo4jTemplate.class) @ConditionalOnRepositoryType(store = "neo4j", type = RepositoryType.IMPERATIVE) @Import(Neo4jRepositoriesRegistrar.class) public class Neo4jRepositoriesAutoConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jTransactionManagerConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jTransactionManagerConfiguration.java new file mode 100644 index 00000000000..53fb41d9954 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jTransactionManagerConfiguration.java @@ -0,0 +1,48 @@ +/* + * Copyright 2012-2024 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.boot.autoconfigure.data.neo4j; + +import org.neo4j.driver.Driver; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.neo4j.core.DatabaseSelectionProvider; +import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager; +import org.springframework.data.neo4j.repository.config.Neo4jRepositoryConfigurationExtension; +import org.springframework.transaction.TransactionManager; + +/** + * Configuration for a Neo4j-backed {@link TransactionManager}. + * + * @author Andy Wilkinson + */ +@Configuration(proxyBeanMethods = false) +class Neo4jTransactionManagerConfiguration { + + @Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_TRANSACTION_MANAGER_BEAN_NAME) + @ConditionalOnMissingBean(TransactionManager.class) + Neo4jTransactionManager transactionManager(Driver driver, DatabaseSelectionProvider databaseNameProvider, + ObjectProvider optionalCustomizers) { + Neo4jTransactionManager transactionManager = new Neo4jTransactionManager(driver, databaseNameProvider); + optionalCustomizers.ifAvailable((customizer) -> customizer.customize((TransactionManager) transactionManager)); + return transactionManager; + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jTransactionalComponentsConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jTransactionalComponentsConfiguration.java new file mode 100644 index 00000000000..d225e3cdbef --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jTransactionalComponentsConfiguration.java @@ -0,0 +1,54 @@ +/* + * Copyright 2012-2024 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.boot.autoconfigure.data.neo4j; + +import org.neo4j.driver.Driver; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.neo4j.core.DatabaseSelectionProvider; +import org.springframework.data.neo4j.core.Neo4jClient; +import org.springframework.data.neo4j.core.Neo4jOperations; +import org.springframework.data.neo4j.core.Neo4jTemplate; +import org.springframework.data.neo4j.core.mapping.Neo4jMappingContext; +import org.springframework.data.neo4j.repository.config.Neo4jRepositoryConfigurationExtension; +import org.springframework.transaction.PlatformTransactionManager; + +/** + * Neo4j components that require a {@link PlatformTransactionManager}. + * + * @author Andy Wilkinson + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnBean(PlatformTransactionManager.class) +class Neo4jTransactionalComponentsConfiguration { + + @Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_CLIENT_BEAN_NAME) + @ConditionalOnMissingBean + Neo4jClient neo4jClient(Driver driver, DatabaseSelectionProvider databaseNameProvider) { + return Neo4jClient.create(driver, databaseNameProvider); + } + + @Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_TEMPLATE_BEAN_NAME) + @ConditionalOnMissingBean(Neo4jOperations.class) + Neo4jTemplate neo4jTemplate(Neo4jClient neo4jClient, Neo4jMappingContext neo4jMappingContext) { + return new Neo4jTemplate(neo4jClient, neo4jMappingContext); + } + +}