Spring Boot - Entity Scan
Spring Boot application automatically recognizes all the entities that are in the same package or its child packages, but issues build failure for entities defined in all other packages.
In order to avoid that, we can use @EntityScan
which can be used to define all the packages that we need our application to scan for entities.
Let's assume the project structure mentioned below to understand how @EntityScan
makes a difference.
Project Structure
com.randomcodez.app
Application.java
UserEntity.java
CategoryEntity.java
com.randomcodez.app.controller
com.randomcodez.app.entity
Article.java
Question.java
com.randomcodez.app.repository
com.randomcodez.app.service
com.randomcodez.common.entity
Topic.java
Tutorial.java
Application.java - without @EntityScan
The basic Spring Boot application is defined as below without using @EntityScan
.
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
When the Spring Boot application is defined without @EntityScan
, then by default the application
- will recognize all the entities defined in the same package
com.randomcodez.app
as it is inside the same package- so, no build issues in using the entities
UserEntity.java
andCategoryEntity.java
- however, we avoid defining entities within the same package
- so, no build issues in using the entities
- will recognize all the entities defined in the package
com.randomcodez.app.entity
as it is inside one of its child packages- so, no build issues in using the entities
Article.java
andQuestion.java
- we encourage defining entities in a separate package like these entities
- so, no build issues in using the entities
- will not recognize the entities defined in the package
com.randomcodez.common.entity
as it is not one of its child packages- so, the build will fail when we use the entities
Topic.java
andTutorial.java
- this can be resolved by defining EntityScan
- so, the build will fail when we use the entities
When we try to use an entity class that is available but not part of the packages scanned for entities, the application build fails with the below error message that says the entity is not a managed type.
Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.randomcodez.commons.entity.Topic
at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:582) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:85) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:75) ~[spring-data-jpa-2.5.4.jar:2.5.4]
at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:66) ~[spring-data-jpa-2.5.4.jar:2.5.4]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:228) ~[spring-data-jpa-2.5.4.jar:2.5.4]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:178) ~[spring-data-jpa-2.5.4.jar:2.5.4]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:161) ~[spring-data-jpa-2.5.4.jar:2.5.4]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:72) ~[spring-data-jpa-2.5.4.jar:2.5.4]
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:319) ~[spring-data-commons-2.5.4.jar:2.5.4]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:323) ~[spring-data-commons-2.5.4.jar:2.5.4]
at org.springframework.data.util.Lazy.getNullable(Lazy.java:230) ~[spring-data-commons-2.5.4.jar:2.5.4]
at org.springframework.data.util.Lazy.get(Lazy.java:114) ~[spring-data-commons-2.5.4.jar:2.5.4]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:329) ~[spring-data-commons-2.5.4.jar:2.5.4]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:144) ~[spring-data-jpa-2.5.4.jar:2.5.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1845) ~[spring-beans-5.3.9.jar:5.3.9]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782) ~[spring-beans-5.3.9.jar:5.3.9]
... 30 common frames omitted
Application.java - With @EntityScan
The basic Spring Boot application using @EntityScan
is as below.
Entity Scan can include multiple packages with a comma between them as shown, which scans all the included packages for entities.
@SpringBootApplication
@EntityScan({"com.randomcodez.commons.entity", "com.randomcodez.app.entity", "com.randomcodez.app"})
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Overall
Spring Boot application with @EnableScan helps us define all the entity packages, which need to be scanned and make available for the application.