24

I have the java configuration for the Spring Data Elaticsearch(using Transport Client) and ESTemplate. Here some except:

@Configuration
@EnableElasticsearchRepositories(basePackages = "subpackage-in-this-project")
@PropertySource("file:path-to-file")
public class ESConfig {

    @Bean
    ElasticsearchTemplate elasticsearchTemplate(Client client) {
        return new ElasticsearchTemplate(client);
    }

    @Bean
    Client client() { 
// configuration of the ES client
   }

}

And I have a config that extends the one above in the different project.

@Configuration
@ComponentScan("package-prefix-that-matches-packages-in-both-projects")
@EnableElasticsearchRepositories(basePackages = "subpackage-in-this-project")
@PropertySource("file:same-path-to-file-as-in-the-config-above")
public class ExtendedESConfig extends ESConfig {

    @Value("index-name")
    private String indexName;

    @Bean
    public String indexName() {
        return indexName;
    }
}

Upon executing a third Spring Boot application, which uses the dependency on the project with ExtendedESConfig, I get this and I can't quite understand why does it happen, started to happen after upgrading to 2.2.9.RELEASE from 2.0.5.RELEASE Spring Boot version.


***************************
APPLICATION FAILED TO START
***************************

Description:

The bean 'elasticsearchTemplate', defined in class path resource [my/package/ESConfig.class], could not be registered. A bean with that name has already been defined in class path resource [my/other/package/ExtendedESConfig.class] and overriding is disabled.

Action:

Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

2020-08-30 16:49:46 ERROR [main] org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter:40 - 

Important remark from my comment:

... sadly, I am not the one who wrote this ES config and built the whole infrastructure around it. ...

At the time of this question, I don't own ExtendedESConfig nor can change it.

improbable
  • 2,308
  • 2
  • 15
  • 28
  • Both config classes are annotated with `@Configuration` and one config extends another. So all beans in parent class will be created twice. Remove `@Configuration` from parent class and try. Also Its not a good practice to use inheritance in config classes. – Hemant Patel Aug 30 '20 at 14:20
  • @PratapiHemantPatel Thanks, I know that this is terrible, but, sadly, I am not the one who wrote this ES config and built the whole infrastructure around it. I gonna try that, but even if this helps this does spawn a number of other problems related to the fact that project with ES config is used standalone in a lot of the cases in too many places. – improbable Aug 30 '20 at 14:39
  • If you own or can update `ExtendedESConfig` class then, you can use excludeFilter on @ComponentScan annotation to exclude `ESConfig` class – Hemant Patel Aug 30 '20 at 16:34
  • I had a similar problem, and in my case the class definition had a `@Service` annotation. This effectively made it a `@Bean` as well which clashed with the `@Bean` definition in the `@Configuration` class. Removing `@Service` fixed the problem for me in Spring 2.6.3. – Asa Aug 17 '22 at 16:49

4 Answers4

12

Or you can add the next property to your application.properties :

spring.main.allow-bean-definition-overriding=true
IKo
  • 4,998
  • 8
  • 34
  • 54
  • 7
    You are stating the obvious because it's literally being said in the logs `Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true`. Apart from that, doesn't relate to my case. Not an answer. – improbable Dec 18 '21 at 14:52
  • 1
    and yet it helps some people – IKo Jul 12 '23 at 13:44
5

The default behaviour of overriding bean has been disabled in Spring Boot 2.1. Spring Boot 2.1 Release Notes

Since you don't own / or don't want to modify both configuration classes. You can exclude parent configuration form your SpringBootApplication class using @ComponentScan

@SpringBootApplication
@ComponentScan(excludeFilters = 
        {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = ESConfig.class)})
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
Hemant Patel
  • 3,160
  • 1
  • 20
  • 29
0

I had a similar problem with my custom springSecurityFilterChain method, in my @Configuration class. The application told me it couldn't create a Bean named springSecurityFilterChain since it was defined elsewhere (in my case, in a Spring Security package, which, as is your case, I couldn't modify).

I found the solution here and it amounted to simply changing my custom method's name; I chose customFilterChain. So it went from

@Bean
public SecurityFilterChain springSecurityFilterChain(HttpSecurity http) throws Exception {
    return http
            .csrf().disable()
            // etc
}

to:

@Bean
public SecurityFilterChain customFilterChain(HttpSecurity http) throws Exception {
    return http
            .csrf().disable()
            // etc
}

Amazingly it worked. Like the article says, Spring builds the bean using the method's name by default. Hope it helps.

  • This is not an answer. This is just a workaround for the issue, not a solution you assume I don't know. And this workaround features Spring Security which is completely out of context here. – improbable Apr 28 '23 at 19:06
-2

find in your modul: resources/application.properties and write:

spring.main.allow-bean-definition-overriding=true

it help you, you need to enable the beans override mechanism.