1. Overview
When using Spring Data JPA we may encounter issues during the bootstrap time. Some of the beans may not be created, causing the application not to start. While the actual stack trace may vary, generally, it looks like this:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerAdapter'
...
Caused by: java.lang.IllegalArgumentException: Not a managed type: ...OurEntity
at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:583)
at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:85)
...
The root cause is a “Not a managed type” exception. In this article, we’ll delve into the possible reasons for this exception and explore its solutions.
2. Missed @Entity Annotation
One possible reason for facing this exception is that we may forget to mark our entity using the @Entity annotation.
2.1. Reproducing the Issue
Let’s assume we have the following entity class:
public class EntityWithoutAnnotation {
@Id
private Long id;
}
We also have its Spring Data JPA repository:
public interface EntityWithoutAnnotationRepository
extends JpaRepository<EntityWithoutAnnotation, Long> {
}
And finally, we have the application class that scans all the classes mentioned above:
@SpringBootApplication
public class EntityWithoutAnnotationApplication {
}
Let’s try to bootstrap the Spring context using this application:
@Test
void givenEntityWithoutAnnotationApplication_whenBootstrap_thenExpectedExceptionThrown() {
Exception exception = assertThrows(Exception.class,
() -> SpringApplication.run(EntityWithoutAnnotationApplication.class));
assertThat(exception)
.getRootCause()
.hasMessageContaining("Not a managed type");
}
As expected, we encountered the “Not a managed type” exception related to our entity.
2.2. Fixing the Issue
Let’s add the @Entity annotation to the fixed version of our entity:
@Entity
public class EntityWithoutAnnotationFixed {
@Id
private Long id;
}
The application and repository classes remain the same. Let’s try to bootstrap the application again:
@Test
void givenEntityWithoutAnnotationApplicationFixed_whenBootstrap_thenRepositoryBeanShouldBePresentInContext() {
ConfigurableApplicationContext context = run(EntityWithoutAnnotationFixedApplication.class);
EntityWithoutAnnotationFixedRepository repository = context
.getBean(EntityWithoutAnnotationFixedRepository.class);
assertThat(repository).isNotNull();
}
We successfully retrieved the ConfigurableApplicationContext instance and obtained the repository instance from there.
3. Migration From javax.persistance to jakarta.persistance
We may face another case of this exception when migrating our application to Jakarta persistence API.
3.1. Reproducing the Issue
Let’s assume we have the next entity:
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
@Entity
public class EntityWithJakartaAnnotation {
@Id
private Long id;
}
Here we started using the jakarta.persistence package, but we’re still using Spring Boot 2. We’ll create the repository and application classes similarly to how we created them in the previous section.
Now, let’s try to bootstrap the application:
@Test
void givenEntityWithJakartaAnnotationApplication_whenBootstrap_thenExpectedExceptionThrown() {
Exception exception = assertThrows(Exception.class,
() -> run(EntityWithJakartaAnnotationApplication.class));
assertThat(exception)
.getRootCause()
.hasMessageContaining("Not a managed type");
}
We face the “Not a managed type” again. Our JPA entities scanner expects us to use javax.persistence.Entity annotation instead of jakarta.persistence.Entity.
3.2. Fixing the Issue
In this case, we have two potential solutions. We can migrate to Spring Boot 3 and Spring Data JPA starts using jakarta.persistence. Alternatively, we can continue using javax.persistence.Entity if we’re not ready for migration.
4. Missed or Misconfigured @EntityScan
Another common situation where we may encounter the “Not a managed type” exception is when our JPA entity scanner can’t find the entity in the expected path.
4.1. Reproducing the Issue
First, we create another entity:
package com.baeldung.spring.entity;
@Entity
public class CorrectEntity {
@Id
private Long id;
}
It has the @Entity annotation and is placed in the entity package. Now, let’s create a repository:
package com.baeldung.spring.repository;
public interface CorrectEntityRepository extends JpaRepository<CorrectEntity, Long> {
}
Our repository is placed in the repository package. Finally, we create an application class:
package com.baeldung.spring.app;
@SpringBootApplication
@EnableJpaRepositories(basePackages = "com.baeldung.spring.repository")
public class WrongEntityScanApplication {
}
It’s placed in the app package. By default, Spring Data looks at repositories under the main class package and its sub-packages. Because of that, we need to specify the base repository package using @EnableJpaRepositories. Now, let’s try to bootstrap the application:
@Test
void givenWrongEntityScanApplication_whenBootstrap_thenExpectedExceptionThrown() {
Exception exception = assertThrows(Exception.class,
() -> run(WrongEntityScanApplication.class));
assertThat(exception)
.getRootCause()
.hasMessageContaining("Not a managed type");
}
We face the “Not a managed type” exception again. The reason is that the logic for entity scan is the same as for repository scan. The packages under our app package were scanned, we didn’t find any entities there and got the exception during the CorrectEntityRepository construction.
4.2. Fixing the Issue
To fix the issue, we can use the @EntityScan annotation.
Let’s create another application class:
@SpringBootApplication
@EnableJpaRepositories(basePackages =
"com.baeldung.spring.repository")
@EntityScan("com.baeldung.spring.entity")
public class WrongEntityScanFixedApplication {
}
Now we specify the repository package using the @EnableJpaRepositories annotation and the entity package using the @EntityScan annotation. Let’s see how it works:
@Test
void givenWrongEntityScanApplicationFixed_whenBootstrap_thenRepositoryBeanShouldBePresentInContext() {
ConfigurableApplicationContext context = run(WrongEntityScanFixedApplication.class);
CorrectEntityRepository repository = context
.getBean(CorrectEntityRepository.class);
assertThat(repository).isNotNull();
}
We successfully bootstrapped the application. We retrieved the CorrectEntityRepository from the context, which means it was built and CorrectEntity was successfully recognized as a JPA Entity.
5. Conclusion
In this tutorial, we’ve explored why we might encounter the “Not a managed type” exception when using Spring Data JPA. We’ve also learned solutions to avoid it. The solution choice depends on the particular case, but understanding the possible reasons help us recognize the exact variant we’re facing.
As usual, the full source code can be found over on GitHub.