Search code examples
jpaspring-bootspring-dataeclipselinkspring-data-jpa

cannot use eclipselink with spring boot


I have a Spring Boot 1.4 app, which I'm trying to use Eclipselink instead Hibernate.
For now, this is what I did:
Removed Hibernate from deps

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

Added eclipselink

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

Configured 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");
}

when I run the app, it creates the tables in database (representing my models), and then, throws this error:

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)

I tried following this and this tutorials, but didn't helped


Solution

  • I think that your problem is an incompatibility between Spring Data version and the EclipseLink version that you use.

    Eclipselink support in SpringBoot seems bad.
    In the pom.xml of spring-boot-dependencies :

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

    in properties tags, you can see :

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

    but zero information about Eclipselink.
    In the same way, in the spring-boot-starter-data-jpa pom, you have a direct dependency for hibernate-core in dependencies tag :

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

    but no dependency for EclipseLink in dependenciesManagement tag. It's a pity since it could have given a way, for projets to use on demand a EclipseLink version compatible with current Spring Boot version in this way :

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

    But as this feature is missing, you must specify the version of Eclipslink in your pom.xml :

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

    In your case, it may be complicated to guess which version of Eclipselink is compatible with the 1.4 spring boot version since your tutorial use the 1.3.2 spring boot version.

    To address your problem, I advise you to try with the same versions (EclipseLink and Spring Boot) as in your tutorial or any working application using SpringBoot and EclipseLink to check that it's well a version compatibility problem.
    If it's ok, then and if you want to update your Spring Boot or EclipseLink version or both, you must do tests to validate a winning combination between Spring Boot, and EclipseLink versions.