不能将 eclipselink 与 Spring Boot 一起使用

Posted

技术标签:

【中文标题】不能将 eclipselink 与 Spring Boot 一起使用【英文标题】:cannot use eclipselink with spring boot 【发布时间】:2016-12-27 13:51:18 【问题描述】:

我有一个 Spring Boot 1.4 应用程序,我正在尝试使用 Eclipselink 代替 Hibernate。 现在,这就是我所做的: 从 deps 中移除了 Hibernate

<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>

添加了eclipse链接

<dependency>
  <groupId>org.eclipse.persistence</groupId>
  <artifactId>eclipselink</artifactId>
  <version>2.6.3</version>
</dependency>

配置JpaBaseConfiguration

@Configuration
public class JpaConfiguration extends JpaBaseConfiguration 

protected JpaConfiguration(DataSource dataSource, JpaProperties properties, ObjectProvider<JtaTransactionManager> jtaTransactionManagerProvider) 
    super(dataSource, properties, jtaTransactionManagerProvider);


 @Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(final EntityManagerFactoryBuilder builder, @Autowired DataSource dataSource) 
    final LocalContainerEntityManagerFactoryBean ret = builder.dataSource(dataSource)
            .packages("com.inkdrop.app.domain.models")
            .persistenceUnit("chathub-perstence-unit")
            .properties(getVendorProperties())
            .build();

    return ret;


@Override
protected AbstractJpaVendorAdapter createJpaVendorAdapter() 
    return new EclipseLinkJpaVendorAdapter();


@Override
protected Map<String, Object> getVendorProperties() 
    return Collections.singletonMap("eclipselink.weaving", "false");

当我运行应用程序时,它会在数据库中创建表(代表我的模型),然后抛出此错误:

Caused by: java.lang.ClassCastException: org.eclipse.persistence.internal.jpa.metamodel.SingularAttributeImpl cannot be cast to javax.persistence.metamodel.PluralAttribute
        at org.eclipse.persistence.internal.jpa.querydef.FromImpl.join(FromImpl.java:485)
        at org.springframework.data.jpa.repository.query.QueryUtils.getOrCreateJoin(QueryUtils.java:596)
        at org.springframework.data.jpa.repository.query.QueryUtils.toExpressionRecursively(QueryUtils.java:524)
        at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.getTypedPath(JpaQueryCreator.java:332)
        at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.build(JpaQueryCreator.java:275)
        at org.springframework.data.jpa.repository.query.JpaQueryCreator.toPredicate(JpaQueryCreator.java:180)
        at org.springframework.data.jpa.repository.query.JpaQueryCreator.create(JpaQueryCreator.java:109)
        at org.springframework.data.jpa.repository.query.JpaQueryCreator.create(JpaQueryCreator.java:49)
        at org.springframework.data.repository.query.parser.AbstractQueryCreator.createCriteria(AbstractQueryCreator.java:109)
        at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:88)
        at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:73)
        at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.<init>(PartTreeJpaQuery.java:118)
        at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$CountQueryPreparer.<init>(PartTreeJpaQuery.java:241)
        at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:68)
        at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:103)
        at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:214)

我尝试遵循 this 和 this 教程,但没有帮助

【问题讨论】:

【参考方案1】:

我认为您的问题是 Spring Data 版本与您使用的 EclipseLink 版本不兼容。

SpringBoot 中的 Eclipselink 支持似乎很糟糕。 在 spring-boot-dependencies 的 pom.xml 中:

<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.4.0.RELEASE</version>

properties标签中,可以看到:

<properties>
 ...
<hibernate.version>5.0.9.Final</hibernate.version>
<hibernate-validator.version>5.2.4.Final</hibernate-validator.version>
 ...
</properties>

但关于 Eclipselink 的信息为零。 同理,在spring-boot-starter-data-jpa pom 中,你在dependencies 标签中有hibernate-core 的直接依赖:

<dependencies>
  ...
       <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.apache.geronimo.specs</groupId>
                <artifactId>geronimo-jta_1.1_spec</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
  ...
<dependencies>

dependenciesManagement 标记中的 EclipseLink 没有依赖关系。很遗憾,因为它本可以让项目以这种方式按需使用与当前 Spring Boot 版本兼容的 EclipseLink 版本:

<dependency>
  <groupId>org.eclipse.persistence</groupId>
  <artifactId>eclipselink</artifactId>
</dependency>

但由于缺少此功能,您必须在 pom.xml 中指定 Eclipslink 的版本:

<dependency>
  <groupId>org.eclipse.persistence</groupId>
  <artifactId>eclipselink</artifactId>
  <version>2.6.3</version>
</dependency>

在您的情况下,由于您的教程使用的是 1.3.2 spring boot 版本,因此猜测 Eclipselink 的哪个版本与 1.4 spring boot 版本兼容可能会很复杂。

为了解决您的问题,我建议您尝试使用与教程中相同的版本(EclipseLink 和 Spring Boot)或使用 SpringBoot 和 EclipseLink 的任何工作应用程序,以检查这是否是版本兼容性问题。 如果没问题,那么如果您想更新 Spring Boot 或 EclipseLink 版本或两者都更新,您必须进行测试以验证 Spring Boot 和 EclipseLink 版本之间的成功组合。

【讨论】:

我让它工作了,但是发现了很多问题和不兼容,我只好回到休眠状态

以上是关于不能将 eclipselink 与 Spring Boot 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

使用 EclipseLink 处理 Spring 事务

在 postgres spring-boot + eclipselink 中保存为 JSON 数据类型的替代解决方案

JPA 2.1、Eclipselink、SQL Server、Spring - NamedStoredProcedureQuery 结果映射

SPRING DATA-JPA + eclipseLink2.0 失败

Oracle 中的 Spring Data JPA + EclipseLink

将 Spring Security 与 JPA 结合使用