【问题标题】:Using Spring Data 2.6.1 with Eclipselink and Jakarta 3, is it possible?将 Spring Data 2.6.1 与 Eclipselink 和 Jakarta 3 一起使用,有可能吗?
【发布时间】: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 相关的旧东西。

  1. 是否可以将 Spring Data 配置为使用 Eclipselink 3 和 Jakarta 3,还是我现在应该坚持使用旧命名空间?
  2. 如果可能的话,你能指出一些当前的例子吗?

显然,可以分叉 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


【解决方案1】:

我在Spring blog 中找到了答案。显然,路线图包括“在 2022 年第四季度”切换到 jakarta 命名空间:

正如昨天在 SpringOne 上宣布的那样,Spring Framework 6 和 Spring Boot 3 计划针对其一般的高端基线 2022 年第四季度的可用性:

Java 17+ (from Java 8-17 in the Spring Framework 5.3.x line)
Jakarta EE 9+ (from Java EE 7-8 in the Spring Framework 5.3.x line)

这一前瞻性基线将为我们的 API 设计和集成工作,照亮您的 应用程序代码和面向未来的框架以及您的 未来许多年的应用。然而,这是有代价的, 课程:基于 Spring Framework 6 和 Spring Boot 3 的应用程序将 运行时至少需要 JDK 17,以及至少 Tomcat 10 / Jetty 11(用于 Jakarta EE 9 兼容性)。更重要的是, 您的应用程序源代码中可能需要进行一些更改: 例如Jakarta EE 9 中 javax 到 jakarta 命名空间的变化 您正在接触 Servlet API、JPA、Bean Validation 等。

因此需要等到 Spring 推出更改。

【讨论】:

    猜你喜欢
    • 2016-12-27
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 2017-03-07
    • 2018-07-02
    • 2019-03-07
    • 2016-01-15
    • 2011-01-28
    相关资源
    最近更新 更多