【发布时间】:2022-01-12 03:48:08
【问题描述】:
我们目前正在增加基于 JPA with Eclipselink 的持久性 Spring 项目的依赖版本。在升级过程中,我了解到 Eclipselink switching to Jakarta namespace 从版本 3.0 开始由于法律原因,如 this thread 中所述。
我们成功更新了代码,以便我们独立使用 Spring Data 的 Jakarta Persistence API 3.0.0。迁移非常简单:
- 将 Eclipselink 版本升级到 3.0.x
- 向 Jakarta 3 添加显式依赖项
- 在代码和
persistence.xml中将javax.persistence替换为jakarta.persistence
现在我正在考虑配置 Spring Data 以将 Eclipselink 与 Jakarta 3.0.0 一起使用,但我注意到 Spring 仍然依赖于 Jakarta 2.2.3。当我在我的 Maven 项目中覆盖版本时,Spring Data 在启动时抱怨:
java.lang.NoClassDefFoundError: javax/persistence/EntityManagerFactory
at org.springframework.data.jpa.util.BeanDefinitionUtils.<clinit>(BeanDefinitionUtils.java:57)
at org.springframework.data.jpa.repository.support.EntityManagerBeanDefinitionRegistrarPostProcessor.postProcessBeanFactory(EntityManagerBeanDefinitionRegistrarPostProcessor.java:72)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:325)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:191)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1290)
at com.mycompany.sandbox.springjpaeclipselinkfix.SpringApp.main(SpringApp.java:12)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: java.lang.ClassNotFoundException: javax.persistence.EntityManagerFactory
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
... 18 common frames omitted
显然,它试图创建一个名为default 的持久性单元,但无法加载javax/persistence/EntityManagerFactory(显然,它现在位于jakarta.persistence 包中)。
我的理解是 Spring Data 的代码依赖于 Jakarta 2,不支持使用 Jakarta 3。但是,应该可以使用 Eclipselink 作为 Spring Data 持久性提供程序,并且 Eclipselink 确实支持 Jakarta 3。此时我很困惑,我找不到任何当前的示例,只有与 javax.persistence 相关的旧东西。
- 是否可以将 Spring Data 配置为使用 Eclipselink 3 和 Jakarta 3,还是我现在应该坚持使用旧命名空间?
- 如果可能的话,你能指出一些当前的例子吗?
显然,可以分叉 Spring Data JPA 的代码并进行迁移,但我没有足够的资源来维护一个分支。
我还发布了我的 pom.xml 的相关部分(其余部分类似于标准 Spring Data 项目):
<project>
...
<properties>
...
<jakarta-persistence.version>3.0.0</jakarta-persistence.version>
<eclipselink.version>3.1.0-M1</eclipselink.version>
</properties>
<dependencies>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</exclusion>
<exclusion>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
</dependency>
...
</dependencies>
<dependencyManagement>
<dependencies>
...
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>${eclipselink.version}</version>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>${jakarta-persistence.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
...
</project>
其他标签:Jakarta EE 9、Jakarta Persistence 3.0、Java 17。
【问题讨论】:
-
我找到了另一个可能有帮助的链接:A Guide to JPA with Spring。我正在研究“在非引导项目中使用 Java 进行 JPA Spring 配置”并创建自定义 PersistenceJPAConfig。
标签: java jpa jakarta-ee spring-data eclipselink