When building large-scale Spring Boot applications, it’s common to modularize your codebase by extracting JPA (@Entity
) classes into separate library JARs. A typical pattern involves creating a shared core library that contains common components such as Entities
, Repositories
, and Services
. This library can then be reused across multiple teams working within the same domain.
However, there are scenarios where you don’t want to import all entities from the shared library into your application. Instead, you might only need to include a few specific entities. This selective import avoids the overhead of loading dozens of unused entities and prevents potential conflicts or schema overlaps that can arise from performing an @EntityScan
over an entire library.
Table of Contents
- Spring Boot JPA Autoconfiguration and Entity Scanning
- The
ManagedClassNameFilter
Interface: Fine-Grained Control Over Entities - Conclusion
Spring Boot JPA Autoconfiguration and Entity Scanning
Spring Boot’s JPA autoconfiguration, specifically in the JpaBaseConfiguration
class, automatically scans for all @Entity
classes within specified base packages. Under the hood, a PersistenceManagedTypesScanner
performs this scan to discover all managed entity classes.
An interesting feature of this scanner is that it can accept an optional ManagedClassNameFilter
bean from the Spring context. This interface lets you filter entities by their fully qualified class names during the scanning phase.
The ManagedClassNameFilter
Interface: Fine-Grained Control Over Entities
By providing a ManagedClassNameFilter
bean, you gain fine-grained control over which entities are included in your application’s persistence context based on their class names.
For example, suppose you want to scan your entire application under the parent package com.myapp
but only want to selectively include two entities — SingleEntity
and FooBar
— from an external library package com.somelibrary.entities
. Suppose that this library contains dozens of other entities you want to exclude.
Here’s how you can configure this:
// other imports skipped
import com.somelibrary.entities.SingleEntity;
import com.somelibrary.entities.FooBar;
@Configuration
@EntityScan(basePackages = {"com.myapp", "com.somelibrary.entities"})
public class JpaEntityConfiguration {
// Tests if the given class name (fully qualified) matches the filter.
// Only matching classes are included in the persistence unit.
@Bean
public ManagedClassNameFilter managedClassNameFilter() {
return className -> className.startsWith("com.myapp")
|| className.equals(SingleEntity.class.getName())
|| className.equals(FooBar.class.getName());
}
}
In this example, Spring Boot will:
- Include all
@Entity
classes undercom.myapp.*
. - Include only the specific
@Entity
classesSingleEntity
andFooBar
fromcom.somelibrary.entities
. - Ignore all other
@Entity
classes from thecom.somelibrary.entities
package.
Why Use ManagedClassNameFilter
?
- Avoid unnecessary overhead: Importing only needed entities improves startup time and memory usage.
- Prevent schema conflicts: Excluding irrelevant or legacy entities helps avoid clashes in database schema generation.
- Maintain clean domain models: Only relevant entities are part of your application’s persistence context.
- Improve modularity: Supports large, multi-team projects with shared domain libraries.
Conclusion
Spring Boot’s JPA autoconfiguration makes entity scanning easy but can sometimes be too broad, especially when working with shared libraries containing many entities. The ManagedClassNameFilter
provides a simple yet powerful way to fine-tune entity registration, allowing selective inclusion based on fully qualified class names.
This approach gives you the best of both worlds: the convenience of Spring Boot autoconfiguration and the precision of manual entity selection.