Spring Boot 3.0+H2启动报错:Not a managed type
解决Spring Boot 3.0中JPA实体未被识别的问题(Not a managed type)
错误日志
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'coffeeService': Unsatisfied dependency expressed through field 'coffeeRepository': Error creating bean with name 'coffeeRepository' defined in com.coffeetime.coffeeshop.repository.CoffeeRepository defined in @EnableJpaRepositories declared on CoffeeshopApplication: Not a managed type: class com.coffeetime.coffeeshop.domain.Coffee Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'coffeeRepository' defined in com.coffeetime.coffeeshop.repository.CoffeeRepository defined in @EnableJpaRepositories declared on CoffeeshopApplication: Not a managed type: class com.coffeetime.coffeeshop.domain.Coffee Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.coffeetime.coffeeshop.domain.Coffee
环境与依赖
- Spring Boot 3.0
- Java 17
- H2内存数据库
Maven依赖配置:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>javax.persistence</groupId> <artifactId>javax.persistence-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency>
配置文件(application.properties)
spring.datasource.url=jdbc:h2:mem:coffeeshopdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password=pass1234 spring.jpa.database-platform=org.hibernate.dialect.H2Dialect spring.jpa.show-sql=true spring.h2.console.enabled=true spring.jpa.defer-datasource-initialization=true
相关代码
CoffeeRepository
import org.springframework.data.jpa.repository.JpaRepository; import com.coffeetime.coffeeshop.domain.Coffee; public interface CoffeeRepository extends JpaRepository<Coffee, Long>{ }
Coffee实体类
@Entity @Table(name = "coffee") public class Coffee { @Id @GeneratedValue(strategy=GenerationType.AUTO) private Long id; @Column(name = "name") @NotEmpty(message = "Coffee name cannot be empty") private String name; @Column(name = "amount") @NotNull(message = "Coffee price cannot be empty") @Min(value = 0, message = "Coffee price must be greater than or equal to 0") private BigDecimal amount; // Getters and Setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public BigDecimal getAmount() { return amount; } public void setAmount(BigDecimal amount) { this.amount = amount; } }
问题现状
包结构已符合实体扫描要求,尝试过添加@EntityScan注解、调整application.properties配置,但问题仍未解决,怀疑与H2数据库有关。
解决方案
问题根源不是H2数据库,而是Spring Boot 3.x的API迁移问题:Spring Boot 3.0基于Jakarta EE 9,所有原javax.persistence下的注解已迁移至jakarta.persistence包,继续使用旧的javax依赖会导致Hibernate无法识别实体类。
步骤1:移除旧的javax.persistence依赖
删除Maven配置中的javax.persistence-api依赖,因为spring-boot-starter-data-jpa已经包含了Jakarta Persistence的相关依赖,无需额外引入。
修改后的Maven依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency>
步骤2:替换实体类的注解包路径
将Coffee实体类中的所有javax.persistence相关注解替换为jakarta.persistence,同时校验注解也要更换为jakarta包下的:
import jakarta.persistence.Entity; import jakarta.persistence.Table; import jakarta.persistence.Id; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Column; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Min; import java.math.BigDecimal; @Entity @Table(name = "coffee") public class Coffee { @Id @GeneratedValue(strategy=GenerationType.AUTO) private Long id; @Column(name = "name") @NotEmpty(message = "Coffee name cannot be empty") private String name; @Column(name = "amount") @NotNull(message = "Coffee price cannot be empty") @Min(value = 0, message = "Coffee price must be greater than or equal to 0") private BigDecimal amount; // 保持原有的Getter和Setter不变 }
步骤3(可选):明确指定扫描路径
如果主启动类不在根包下,可以在主启动类上添加以下注解确保扫描范围:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.boot.autoconfigure.domain.EntityScan; @SpringBootApplication @EntityScan(basePackages = "com.coffeetime.coffeeshop.domain") @EnableJpaRepositories(basePackages = "com.coffeetime.coffeeshop.repository") public class CoffeeshopApplication { public static void main(String[] args) { SpringApplication.run(CoffeeshopApplication.class, args); } }
完成以上步骤后重新启动应用,即可解决"Not a managed type"错误。
内容的提问来源于stack exchange,提问作者NecmiK
相关产品推荐
相关产品推荐

