Spring Framework
UnsatisfiedDependencyException
Bean Creation Error
Dependency Injection
demoRestController

org.springframework.beans.factory.UnsatisfiedDependencyException Error creating bean with name 'demoRestController'

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

UnsatisfiedDependencyException is thrown when Spring cannot inject a required dependency into a bean. The error Error creating bean with name 'demoRestController': Unsatisfied dependency expressed through field 'service' typically means the injected service class is missing a @Service or @Component annotation, is not in a package scanned by @ComponentScan, or has its own unsatisfied dependencies (cascading failure). The fix involves checking annotations, package scanning, constructor parameters, and the full stack trace to find the root bean that failed.

The Error Message

 
1org.springframework.beans.factory.UnsatisfiedDependencyException:
2  Error creating bean with name 'demoRestController':
3  Unsatisfied dependency expressed through field 'demoService';
4  nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
5  No qualifying bean of type 'com.example.DemoService' available

This tells you: Spring tried to create demoRestController, found it needs a DemoService, but could not find a bean of that type in the application context.

Cause 1: Missing @Service or @Component Annotation

java
1// BROKEN — no annotation, Spring does not know about this class
2public class DemoService {
3    public String getData() {
4        return "Hello";
5    }
6}
7
8// FIX — add @Service annotation
9@Service
10public class DemoService {
11    public String getData() {
12        return "Hello";
13    }
14}
java
1@RestController
2public class DemoRestController {
3
4    @Autowired
5    private DemoService demoService;  // Fails without @Service on DemoService
6
7    @GetMapping("/demo")
8    public String demo() {
9        return demoService.getData();
10    }
11}

Spring only manages classes annotated with @Component, @Service, @Repository, @Controller, or @Configuration. Without these, the class is invisible to dependency injection.

Cause 2: Wrong Package — Not Scanned

 
1src/main/java/
2  com/example/demo/
3    DemoApplication.java         ← @SpringBootApplication here
4    controller/
5      DemoRestController.javaScanned (subpackage of com.example.demo)
6  com/other/
7    DemoService.javaNOT scanned (different package tree)
java
1// DemoApplication.java — scans com.example.demo and subpackages by default
2@SpringBootApplication
3public class DemoApplication {
4    public static void main(String[] args) {
5        SpringApplication.run(DemoApplication.class, args);
6    }
7}
8
9// FIX: Either move DemoService under com.example.demo
10// Or explicitly scan additional packages:
11@SpringBootApplication
12@ComponentScan(basePackages = {"com.example.demo", "com.other"})
13public class DemoApplication {
14    public static void main(String[] args) {
15        SpringApplication.run(DemoApplication.class, args);
16    }
17}

@SpringBootApplication includes @ComponentScan which scans the package of the main class and all subpackages. Classes in sibling or parent packages are not discovered.

Cause 3: Interface Without Implementation

java
1// Interface defined
2public interface DemoService {
3    String getData();
4}
5
6// BROKEN — implementation exists but is not annotated
7public class DemoServiceImpl implements DemoService {
8    @Override
9    public String getData() { return "Hello"; }
10}
11
12// FIX — annotate the implementation
13@Service
14public class DemoServiceImpl implements DemoService {
15    @Override
16    public String getData() { return "Hello"; }
17}
java
1@RestController
2public class DemoRestController {
3
4    @Autowired
5    private DemoService demoService;  // Spring injects DemoServiceImpl
6
7    @GetMapping("/demo")
8    public String demo() {
9        return demoService.getData();
10    }
11}

When injecting by interface type, the concrete implementation class must be annotated. Spring resolves the interface to its annotated implementation.

Cause 4: Cascading Dependency Failure

java
1@Service
2public class DemoService {
3
4    @Autowired
5    private DemoRepository demoRepository;  // This also fails
6
7    public String getData() {
8        return demoRepository.findData();
9    }
10}
11
12// DemoRepository is missing @Repository annotation
13// This causes DemoService to fail, which causes DemoRestController to fail
 
UnsatisfiedDependencyException: Error creating bean 'demoRestController'
  Caused by: UnsatisfiedDependencyException: Error creating bean 'demoService'
    Caused by: NoSuchBeanDefinitionException: No bean of type 'DemoRepository'

Read the full stack trace — the root cause is at the bottom. The controller fails because the service fails because the repository is not a bean.

Cause 5: Missing Dependency or Configuration

java
1// JPA Repository — requires spring-boot-starter-data-jpa
2@Repository
3public interface DemoRepository extends JpaRepository<DemoEntity, Long> {
4}
xml
1<!-- pom.xml — missing dependency -->
2<!-- FIX: Add this -->
3<dependency>
4    <groupId>org.springframework.boot</groupId>
5    <artifactId>spring-boot-starter-data-jpa</artifactId>
6</dependency>
7<dependency>
8    <groupId>com.h2database</groupId>
9    <artifactId>h2</artifactId>
10    <scope>runtime</scope>
11</dependency>
properties
# application.properties — JPA requires a datasource
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name=org.h2.Driver

JPA repositories need spring-boot-starter-data-jpa and a configured datasource. Missing either causes the repository bean creation to fail, cascading up to the controller.

Cause 6: Constructor Injection Issues

java
1@RestController
2public class DemoRestController {
3
4    private final DemoService demoService;
5
6    // Constructor injection — preferred over @Autowired fields
7    public DemoRestController(DemoService demoService) {
8        this.demoService = demoService;
9    }
10
11    @GetMapping("/demo")
12    public String demo() {
13        return demoService.getData();
14    }
15}
16
17// If DemoService bean is missing, the error message is:
18// Parameter 0 of constructor in DemoRestController required a bean
19// of type 'DemoService' that could not be found

Constructor injection produces clearer error messages than field injection. The error explicitly states which constructor parameter could not be resolved.

Debugging Checklist

java
1// 1. Check the class has an annotation
2@Service  // or @Component, @Repository, @Configuration
3public class DemoService { }
4
5// 2. Check the package is scanned
6// Main class in com.example.demo → scans com.example.demo.**
7// Service must be in com.example.demo or a subpackage
8
9// 3. Check for qualifying beans (multiple implementations)
10@Service
11@Primary  // Resolves ambiguity when multiple beans match
12public class DemoServiceImpl implements DemoService { }
13
14// 4. Check the full stack trace — find the root cause
15// UnsatisfiedDependencyException chains show the full dependency path
16
17// 5. Enable debug logging
18// application.properties:
19// logging.level.org.springframework=DEBUG

Common Pitfalls

  • Annotating the interface instead of the implementation: @Service on an interface does nothing if there is no concrete implementation also annotated. Spring needs an instantiable class to create a bean. Put @Service on the implementation class, not the interface.
  • Service class in a package outside component scan: @SpringBootApplication scans its own package and subpackages. A service in com.other.service is invisible if the main class is in com.example.app. Add @ComponentScan(basePackages = {...}) or restructure packages.
  • Multiple beans of the same type without @Primary or @Qualifier: If two classes implement the same interface and both are annotated, Spring throws NoUniqueBeanDefinitionException. Use @Primary on the preferred bean or @Qualifier("beanName") at the injection point.
  • Not reading the full stack trace: The UnsatisfiedDependencyException on the controller is often caused by a deeper failure in a service or repository. The root cause (at the bottom of the stack trace) reveals the actual missing bean or configuration error.
  • Missing Spring Boot starter dependency: JPA repositories need spring-boot-starter-data-jpa, web controllers need spring-boot-starter-web, and security needs spring-boot-starter-security. A missing starter means Spring cannot create the infrastructure beans your code depends on.

Summary

  • UnsatisfiedDependencyException means Spring cannot find or create a required bean
  • Check that the dependency class has @Service, @Component, or @Repository
  • Ensure the class is in a package scanned by @ComponentScan (subpackage of the main class)
  • Read the full stack trace — the root cause is at the bottom of the exception chain
  • Use constructor injection for clearer error messages and easier testing
  • Add @Primary or @Qualifier when multiple beans of the same type exist

Course illustration
Course illustration

All Rights Reserved.