Spring Boot API启动报错NoClassDefFoundError: javax/persistence/EntityManagerFactory
问题:Spring Boot启动时出现
javax.persistence.EntityManagerFactory类找不到错误 问题背景
我正在开发第一个Spring Boot Java API,计划实现查询所有人员、按ID查询单个人员以及创建人员的功能。编译已成功,但执行./mvnw spring-boot:run时启动失败,报错如下:
java.lang.NoClassDefFoundError: javax/persistence/EntityManagerFactory at org.springframework.data.jpa.util.BeanDefinitionUtils.<clinit>(BeanDefinitionUtils.java:57) ~[spring-data-jpa-2.7.18.jar:2.7.18] at org.springframework.data.jpa.repository.support.EntityManagerBeanDefinitionRegistrarPostProcessor.postProcessBeanFactory(EntityManagerBeanDefinitionRegistrarPostProcessor.java:72) ~[spring-data-jpa-2.7.18.jar:2.7.18] at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:325) ~[spring-context-5.3.31.jar:5.3.31] at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:191) ~[spring-context-5.3.31.jar:5.3.31] at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:756) ~[spring-context-5.3.31.jar:5.3.31] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:572) ~[spring-context-5.3.31.jar:5.3.31] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.18.jar:2.7.18] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732) ~[spring-boot-2.7.18.jar:2.7.18] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:409) ~[spring-boot-2.7.18.jar:2.7.18] at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.18.jar:2.7.18] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) ~[spring-boot-2.7.18.jar:2.7.18] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1289) ~[spring-boot-2.7.18.jar:2.7.18] at com.example.demo.DemoApplication.main(DemoApplication.java:10) ~[classes/:na] Caused by: java.lang.ClassNotFoundException: javax.persistence.EntityManagerFactory at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581) ~[na:na] at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[na:na] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:527) ~[na:na] ... 13 common frames omitted
项目结构
. ├── mvnw ├── mvnw.cmd ├── pom.xml ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── controller │ │ │ │ └── PersonController.java │ │ │ ├── DemoApplication.java │ │ │ ├── model │ │ │ │ └── Person.java │ │ │ └── repository │ │ │ └── PersonRepository.java │ │ └── resources │ │ ├── application.properties │ │ ├── data.sql │ │ ├── schema.sql │ │ ├── static │ │ └── templates │ └── test └── target
相关代码
PersonController.java
package com.example.demo.controller; import com.example.demo.model.Person; import com.example.demo.repository.PersonRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/api/persons") public class PersonController { @Autowired private PersonRepository personRepository; @GetMapping public List<Person> getAllPersons() { return personRepository.findAll(); } @GetMapping("/{id}") public Person getPersonById(@PathVariable Long id) { return personRepository.findById(id).orElse(null); } @PostMapping public Person createPerson(@RequestBody Person person) { return personRepository.save(person); } }
Person.java
package com.example.demo.model; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import java.time.LocalDate; @Entity public class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String nom; private String prenom; private LocalDate dateNaissance; private String numTelephone; private String mail; }
pom.xml配置
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>demo</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.18</version> <relativePath/> </parent> <properties> <java.version>11</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>jakarta.persistence</groupId> <artifactId>jakarta.persistence-api</artifactId> <version>3.1.0</version> </dependency> <!--<dependency> <groupId>javax.persistence</groupId> <artifactId>javax.persistence-api</artifactId> <version>2.2</version> </dependency>--> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>11</source> <target>11</target> </configuration> </plugin> </plugins> </build> </project>
尝试过的操作与疑问
我使用OpenJDK 11和Maven,了解到javax已被jakarta替代,因此在pom.xml中引入了jakarta.persistence-api依赖,但错误仍指向javax;尝试替换为javax.persistence-api则编译失败,恳请提供解决方案。
解决方案
核心问题是Spring Boot 2.x版本仅支持JPA的javax命名空间,不兼容jakarta命名空间,jakarta是Spring Boot 3.x及以上版本的标准。
步骤1:统一命名空间,改用javax.persistence
- 修改
Person.java中的注解,将jakarta.persistence替换为javax.persistence,同时补充getter/setter方法(否则JPA和JSON序列化会失败):
package com.example.demo.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import java.time.LocalDate; @Entity public class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String nom; private String prenom; private LocalDate dateNaissance; private String numTelephone; private String mail; // 补充getter/setter public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } public String getPrenom() { return prenom; } public void setPrenom(String prenom) { this.prenom = prenom; } public LocalDate getDateNaissance() { return dateNaissance; } public void setDateNaissance(LocalDate dateNaissance) { this.dateNaissance = dateNaissance; } public String getNumTelephone() { return numTelephone; } public void setNumTelephone(String numTelephone) { this.numTelephone = numTelephone; } public String getMail() { return mail; } public void setMail(String mail) { this.mail = mail; } }
- 修改pom.xml,移除
jakarta.persistence-api依赖,无需手动引入javax.persistence-api(spring-boot-starter-data-jpa已包含该依赖,手动引入可能导致版本冲突):
<!-- 移除jakarta依赖 --> <!-- <dependency> <groupId>jakarta.persistence</groupId> <artifactId>jakarta.persistence-api</artifactId> <version>3.1.0</version> </dependency> --> <!-- 注释或删除之前的javax依赖,避免重复引入 -->
步骤2:清理并重新构建
执行以下命令清理缓存并启动项目:
./mvnw clean install ./mvnw spring-boot:run
补充说明
如果想使用jakarta命名空间,需要升级到Spring Boot 3.x版本,但Spring Boot 3.x要求Java版本至少为17,需先升级Java版本到17及以上,再将pom.xml中parent版本改为3.x(如3.2.5),同时保持实体类的jakarta注解不变。
内容的提问来源于stack exchange,提问作者Guillaume
相关产品推荐
相关产品推荐

