-
Notifications
You must be signed in to change notification settings - Fork 192
Conflicting transactionInterceptor bean when using Spring Boot 3.0.2 and Couchbase Starter #1665
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@cjp421 I think you are missing one of the Requirements documented in the official docs. That is
|
I don't know if the documentation should be improved? I'm not using It was also suggested that the couchbase starter should use a different name or use a bean post processor to modify the interceptor provided by the framework. Would that be a more elegant solution than just allowing bean overrides any time the couchbase starter is used? |
I didn't realize this was preventing the application to initialize as all our test application have the property set. I would love to fix this, but I don't have any great solutions.
The application property should be mentioned very near the beginning - perhaps in the Installation and Configuration section. Also If the documentation reference the exception, then a search of the documentation would find the explanation.
It should, and it would if we omit the transactionInterceptor bean, but then couchbase transactions won't work, unless the user included the transactionInterceptor bean in their Configuration class, and the application property. This is probably the best solution.
As far as I can tell, the bean must have that name, as that is what the framework uses for the bean dependency in transactionAdvisor() in ProxyTransactionManagementConfiguration. A post-processor won't help as the critical difference is in the actual processing, not the post-processing. |
IMO, a post-processor could help here. For example, I think you could replace the @Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static BeanPostProcessor transactionInterceptorCustomizer(
ObjectProvider<TransactionManager> transactionManagerProvider) {
return new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof TransactionInterceptor) {
TransactionAttributeSource transactionAttributeSource = new AnnotationTransactionAttributeSource();
TransactionManager transactionManager = transactionManagerProvider.getObject();
TransactionInterceptor interceptor = new CouchbaseTransactionInterceptor(transactionManager,
transactionAttributeSource);
interceptor.setTransactionAttributeSource(transactionAttributeSource);
if (transactionManager != null) {
interceptor.setTransactionManager(transactionManager);
}
return interceptor;
}
return bean;
}
};
} This is untested but hopefully it will at least serve as a useful starting point. You may want to do a bean name check as well in case there's another |
Thanks, I appreciate the effort. And thanks for showing what a postProcessor is. [EDIT: I did find a way around this but it seems like a terrible hack] But - transactionInterceptorCustomizer is not getting called for transactionInterceptor (it does get called for a lot of other beans). It looks like the issue is that TransactionInterceptor is instantiated (including the postProcessors being called) before the BeanPostProcessor provided by transactionInterceptorCustomizer is registered as a post-processor because org.springframework.transaction.config.internalTransactionAdvisor is considered for an advisor. during the creation of the transactionInterceptorCustomizer bean, the call to findCandidateAdvisors() results in transactionInterceptor being instantiated and the postProcessors being called - but at that point, the transactionInterceptorCustomizer postProcessor does not yet exist.
To allow the BeanPostProcessor provided by transactionInterceptorCustomizer to be called as a post-processor for transactionInterceptor when transactionInterceptor is being created/initialized DURING the creation/initialization of the BeanPostProcessor, it's necessary that transactionInterceptorCustomizer registers the BeanPostProcessor it is creating.
|
Ah, sorry. I hadn't considered the timing of the creation of the interceptor bean and the effect that would have on being able to post-process it. I agree that calling |
Originally created spring-projects/spring-boot#34209 but was instructed to create a new issue here.
Receiving the following error when using Spring Boot 3.0.2 and spring-boot-starter-data-couchbase:
The bean 'transactionInterceptor', defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [com/example/demo/CouchbaseConfig.class] and overriding is disabled.
To recreate:
3, Try and start the application
./gradlew bootRun
Is there something I'm missing with Spring Boot 3.0.2 and Couchbase starter?
https://github.com/spring-projects/spring-data-couchbase/blob/main/src/main/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.java#L377-L388
https://github.com/spring-projects/spring-framework/blob/main/spring-tx/src/main/java/org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.java#L65-L74
The text was updated successfully, but these errors were encountered: