SpringBoot
BeanDefinitionOverrideException
Spring Framework
Java
Exception Handling

SpringBoot - BeanDefinitionOverrideException Invalid bean definition

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

BeanDefinitionOverrideException happens when Spring finds multiple bean definitions with the same name while overriding is disabled. This error is a safety feature that prevents accidental replacement of configuration. The best fix is resolving naming and wiring intent, not blindly enabling global override.

Why the Exception Happens

Common causes:

  • Two @Bean methods with same method name.
  • Two components explicitly named the same.
  • Test configuration colliding with application bean names.
  • Custom beans colliding with auto-configuration names.

Example collision:

java
1@Configuration
2public class PrimaryConfig {
3    @Bean
4    public MyService myService() {
5        return new MyServiceImplA();
6    }
7}
8
9@Configuration
10public class SecondaryConfig {
11    @Bean
12    public MyService myService() {
13        return new MyServiceImplB();
14    }
15}

Both definitions map to bean name myService.

Fix with Explicit Names and Qualifiers

Give implementations distinct names and inject by qualifier.

java
1@Configuration
2public class ServiceConfig {
3
4    @Bean("myServiceA")
5    public MyService myServiceA() {
6        return new MyServiceImplA();
7    }
8
9    @Bean("myServiceB")
10    public MyService myServiceB() {
11        return new MyServiceImplB();
12    }
13}

Injection:

java
1import org.springframework.beans.factory.annotation.Qualifier;
2import org.springframework.stereotype.Service;
3
4@Service
5public class BillingService {
6    private final MyService myService;
7
8    public BillingService(@Qualifier("myServiceA") MyService myService) {
9        this.myService = myService;
10    }
11}

This makes dependency intent explicit and reviewable.

@Primary Is Not a Name-Collision Fix

@Primary helps when multiple beans of same type exist for autowiring by type. It does not resolve duplicate bean name registration.

Use @Primary only after bean names are distinct and valid.

Control Scan Boundaries

Overly broad scanning can pull in unintended classes and create collisions.

java
@SpringBootApplication(scanBasePackages = "com.example.app")
public class App {
}

In tests, isolate @TestConfiguration and avoid loading full app context unless required.

Should You Enable Bean Override

Spring allows override via property:

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

Use this only when replacement is deliberate and documented. As a default policy, it can hide configuration bugs and create surprising environment-specific behavior.

Prefer Conditional Beans for Environment Differences

When different implementations are needed per profile or property, use conditional registration.

java
1@Bean
2@ConditionalOnProperty(name = "feature.mock-service", havingValue = "true")
3public MyService mockService() {
4    return new MyServiceImplB();
5}

Conditional wiring communicates intent better than silent overriding.

Debugging Workflow

When exception occurs:

  1. Read the two conflicting bean definitions in startup message.
  2. Search codebase for the duplicated bean name.
  3. Check imported test configs and auto-config classes.
  4. Rename or scope beans explicitly.

Enable startup debug report for more context:

properties
debug=true

This often reveals auto-configuration sources involved in collisions.

Preventive Practices

  • Use descriptive bean method names.
  • Avoid generic names reused across modules.
  • Keep architecture tests for duplicate naming patterns.
  • Review new config classes for overlap with existing modules.

Preventing collisions in reviews is cheaper than startup-failure triage later.

Another useful safeguard is module-level naming conventions. For example, prefix infrastructure beans with infra and feature beans with bounded-context names. This lowers collision probability as codebase size grows and makes startup diagnostics easier to interpret when conflicts still occur. If your team uses shared starter modules, publish a documented list of exported bean names. This avoids accidental collisions when application modules define similarly named custom beans. This registry also improves architectural visibility during large refactoring efforts.

Common Pitfalls

  • Enabling global override as first reaction.
  • Assuming @Primary resolves same-name registrations.
  • Reusing generic bean names across unrelated configs.
  • Mixing test and production config in one scanned package.
  • Ignoring auto-config bean names when defining custom replacements.

Summary

  • The exception signals duplicate bean names with override protection active.
  • Resolve conflicts with explicit names and qualifier-based injection.
  • Use @Primary only for type preference, not name collision fixes.
  • Prefer conditional registration over global override settings.
  • Keep scan scope and config boundaries intentional to avoid future collisions.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.