Я хочу создать свой первый Java API с помощью Spring, поэтому для начала я решил создать простой API, который позволит перечислять всех людей, одного человека по идентификатору и создавать одного человека. Я успешно компилировал, но когда я запускаю ./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:
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:
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, но не знаю, почему ошибка все еще относится к javax.
Я попытался заменить зависимость jakarta.persistence на javax.persistence, но сейчас она не компилируется, поэтому я думаю, что это не очень хороший способ.
У кого-нибудь есть идеи, как помочь новичку в Java, пожалуйста?
Да, я забыл заменить импорт, когда пытался использовать зависимость Javax. В моем случае мне придется остаться на Java 11, поэтому большое спасибо
Java 17 не имеет ничего общего с JakartaEE. Вы можете с радостью перейти на Java17 без необходимости перехода на JakartaEE
.
В новых версиях Spring импорт пакета «javax.xxx» должен быть заменен на «jakarta.xxx». Однако, поскольку вы используете более старую версию загрузки Spring (2.7.18), вам не нужно ее менять. Вам необходимо продолжить импорт «javax.xxx». (или обновиться до версии Spring 3.x).
Стоит отметить, что переход на Spring Boot 3.x также требует обязательного обновления до Java 17.
Удалите зависимость jakarta.persistence-api
: поскольку вы используете Spring Boot 2.x, вам следует использовать пакет javax.persistence
. Новый пакет jakarta.persistence
предназначен для Spring Boot 3.x и более поздних версий. и попробуйте пересобрать проект
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
Удалите
jakarta.persistence-api
, исправьте импорт вjavax.persistence
(как в старой версии Spring Boot) и перезапустите. Все необходимые зависимости уже являются частьюspring-boot-starter-data-jpa
, не пытайтесь быть умнее этих зависимостей (если только вы не очень уверены в том, что делаете). Или удалите указанную зависимость, обновите Spring Boot 3.3.1 и используйте JDK17.