@EntityScan
@ComponentScan
Spring Framework
Annotations
Java Development

Difference between EntityScan and ComponentScan

Master System Design with Codemia

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

Introduction

@ComponentScan and @EntityScan are two distinct Spring Boot annotations that scan the classpath for different types of classes. @ComponentScan discovers Spring-managed beans (classes annotated with @Component, @Service, @Repository, @Controller) and registers them in the application context. @EntityScan discovers JPA entity classes (annotated with @Entity) and registers them with the JPA EntityManagerFactory. They serve different purposes and operate on different class types — confusing them is a common source of "bean not found" and "entity not managed" errors.

@ComponentScan

@ComponentScan tells Spring where to look for beans. By default, @SpringBootApplication includes @ComponentScan scanning the package of the main class and all sub-packages:

java
1// Automatically scans com.example.app and sub-packages
2@SpringBootApplication
3public class MyApplication {
4    public static void main(String[] args) {
5        SpringApplication.run(MyApplication.class, args);
6    }
7}
8
9// This service is auto-discovered because it's in a sub-package
10package com.example.app.service;
11
12@Service
13public class UserService {
14    public String getUser() { return "Alice"; }
15}

To scan additional packages outside the default:

java
1@SpringBootApplication
2@ComponentScan(basePackages = {
3    "com.example.app",
4    "com.example.shared.services"
5})
6public class MyApplication { }

@ComponentScan detects classes with these stereotype annotations:

AnnotationPurpose
@ComponentGeneric Spring-managed bean
@ServiceBusiness logic layer
@RepositoryData access layer (adds exception translation)
@ControllerSpring MVC web controller
@RestControllerREST API controller (@Controller + @ResponseBody)
@ConfigurationConfiguration class with @Bean methods

@EntityScan

@EntityScan tells JPA (Hibernate) where to find @Entity classes. It does not register them as Spring beans — it registers them with the EntityManagerFactory so Hibernate can map them to database tables:

java
1package com.example.domain;
2
3import jakarta.persistence.*;
4
5@Entity
6@Table(name = "users")
7public class User {
8    @Id
9    @GeneratedValue(strategy = GenerationType.IDENTITY)
10    private Long id;
11
12    private String name;
13    private String email;
14
15    // getters and setters
16}

If your entities are in a package outside the main application package, you need @EntityScan:

java
@SpringBootApplication
@EntityScan(basePackages = "com.example.domain")
public class MyApplication { }

Without @EntityScan, Hibernate only discovers entities in the main application package and its sub-packages.

When You Need Each Annotation

java
1// Typical multi-module project structure:
2// com.example.app        — main application class
3// com.example.domain     — JPA entities (separate module)
4// com.example.services   — service beans (separate module)
5// com.example.web        — controllers
6
7@SpringBootApplication  // Scans com.example.app.* by default
8@ComponentScan(basePackages = {
9    "com.example.app",
10    "com.example.services",
11    "com.example.web"
12})
13@EntityScan(basePackages = "com.example.domain")
14@EnableJpaRepositories(basePackages = "com.example.domain")
15public class MyApplication { }

Note that @EnableJpaRepositories is a third annotation that scans for Spring Data JPA repository interfaces — it is separate from both @ComponentScan and @EntityScan.

Side-by-Side Comparison

Feature@ComponentScan@EntityScan
What it scans for@Component, @Service, @Repository, @Controller@Entity, @Embeddable, @MappedSuperclass
Registers withSpring ApplicationContextJPA EntityManagerFactory
Included in @SpringBootApplicationYes (implicitly)Yes (for the main package only)
When to add explicitlyBeans in external packagesEntities in external packages
Modulespring-contextspring-boot-autoconfigure

Configuring with Spring Boot Properties

You can also configure entity scanning via application.properties instead of annotations:

properties
# application.properties
spring.jpa.mapping-resources=META-INF/orm.xml

However, annotation-based scanning with @EntityScan is the standard approach in Spring Boot.

Common Pitfalls

  • Using @ComponentScan to find JPA entities: @ComponentScan discovers Spring beans, not JPA entities. Adding @ComponentScan("com.example.domain") does not make Hibernate aware of @Entity classes in that package. You need @EntityScan for entities.
  • Using @EntityScan to find Spring beans: Conversely, @EntityScan does not register classes as Spring beans. If your @Service class is in a package only covered by @EntityScan, it will not be available for dependency injection. Use @ComponentScan for beans.
  • Forgetting @EnableJpaRepositories alongside @EntityScan: When entities are in an external package, their Spring Data repositories are usually in the same package. @EntityScan finds the entities, but you also need @EnableJpaRepositories to discover the repository interfaces.
  • Overriding @SpringBootApplication default scanning: Adding @ComponentScan with explicit basePackages replaces the default scan of the main class package. If you specify @ComponentScan("com.example.shared") without also including the main package, beans in the main package are no longer discovered.
  • Duplicate bean registration from overlapping scans: If two @ComponentScan base packages overlap (e.g., com.example and com.example.service), beans in the overlapping area are scanned twice. Spring usually handles this gracefully by ignoring duplicates, but custom BeanDefinitionRegistryPostProcessor configurations may cause conflicts.

Summary

  • @ComponentScan discovers Spring beans (@Component, @Service, @Repository, @Controller) and registers them in the Spring context
  • @EntityScan discovers JPA entities (@Entity, @Embeddable) and registers them with the Hibernate EntityManagerFactory
  • Both are implicitly included in @SpringBootApplication for the main class package and its sub-packages
  • Add explicit annotations only when classes live outside the main application package (common in multi-module projects)
  • Also add @EnableJpaRepositories when JPA repository interfaces are in external packages
  • Never use one annotation when you need the other — they serve completely different purposes

Course illustration
Course illustration

All Rights Reserved.