将 Spring Data 2.6.1 与 Eclipselink 和 Jakarta 3 一起使用,这可能吗?

Using Spring Data 2.6.1 with Eclipselink and Jakarta 3, is it possible?

我们目前正在使用基于 JPA with Eclipselink. During the upgrade process I learned about Eclipselink switching to Jakarta namespace starting with version 3.0 due to legal reasons as explained in .

的持久性更新 Spring 项目的依赖版本

我们成功地更新了代码,以便我们使用来自 Spring 数据的 Jakarta Persistence API 3.0.0 独立。迁移非常简单:

现在我正在考虑配置 Spring 数据以将 Eclipselink 与 Jakarta 3.0.0 一起使用,但我注意到 Spring 仍然依赖于 JAXB 2.2.3。当我覆盖我的 Maven 项目中的版本时,Spring 数据在启动时抱怨:

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 数据持久性提供程序,并且 Eclipselink 确实支持 Jakarta 3。我现在很困惑,我找不到任何当前的例子,只有与 [=13= 有关的旧东西].

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

显然,可以分叉 Spring Data JPA 代码并进行迁移,但我没有足够的资源来维护分支。

我也发布了我的 pom.xml 的相关部分(其余部分类似于标准 Spring 数据项目):

<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、Java17.

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

As announced at SpringOne yesterday, Spring Framework 6 and Spring Boot 3 are planned towards a high-end baseline for their general availability in Q4 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)

This forward-looking baseline will provide significant benefits in our API design and integration efforts, shining through to your application code and future-proofing the framework as well as your applications for many years to come. However, it comes at a cost, of course: Spring Framework 6 and Spring Boot 3 based applications will require a minimum of JDK 17 at runtime, as well as a minimum of Tomcat 10 / Jetty 11 (for Jakarta EE 9 compatibility). Even more importantly, there might be some changes required in your application source code: e.g. the javax to jakarta namespace change in Jakarta EE 9 wherever you’re touching the Servlet API, JPA, Bean Validation, etc.

因此,需要等待 Spring 推出更改。