spring-projects / spring-data-jpa

Simplifies the development of creating a JPA-based data access layer.
https://spring.io/projects/spring-data-jpa/
Apache License 2.0
2.92k stars 1.39k forks source link

Incompatible version of jsqlparser between spring-data-jpa and spring-data-jdbc (3.3.0) #3494

Closed Nowheresly closed 3 weeks ago

Nowheresly commented 3 weeks ago

Hi,

I have a project that uses both spring-data-jpa and spring-data-jdbc with spring boot version 3.3.0


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

Here is a excerpt of my maven dependency tree:

[INFO] +- org.springframework.boot:spring-boot-starter-data-jdbc:jar:3.3.0:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-jdbc:jar:3.3.0:compile
[INFO] |  |  +- com.zaxxer:HikariCP:jar:5.1.0:compile
[INFO] |  |  \- org.springframework:spring-jdbc:jar:6.1.8:compile
[INFO] |  \- org.springframework.data:spring-data-jdbc:jar:3.3.0:compile
[INFO] |     \- org.springframework.data:spring-data-relational:jar:3.3.0:compile
[INFO] |        \- com.github.jsqlparser:jsqlparser:jar:4.6:compile
[INFO] +- org.springframework.boot:spring-boot-starter-data-jpa:jar:3.3.0:compile

When starting my project, I get this error:

java.lang.NoClassDefFoundError: net/sf/jsqlparser/statement/select/Values
    at org.springframework.data.jpa.repository.query.JSqlParserQueryEnhancer.getProjection(JSqlParserQueryEnhancer.java:410)
    at org.springframework.data.jpa.repository.query.StringQuery.getProjection(StringQuery.java:102)
    at org.springframework.data.jpa.repository.query.StringQuery.isDefaultProjection(StringQuery.java:147)
    at org.springframework.data.jpa.repository.query.NativeJpaQuery.getTypeToQueryFor(NativeJpaQuery.java:82)
    at org.springframework.data.jpa.repository.query.NativeJpaQuery.createJpaQuery(NativeJpaQuery.java:71)
    at org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery.doCreateQuery(AbstractStringBasedJpaQuery.java:124)
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:243)
    at org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:223)
    at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:92)
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:152)
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:140)
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:170)
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:158)
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:164)
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:70)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:392)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:136)

Indeed, the class net/sf/jsqlparser/statement/select/Values is only available in version 4.7+ of jsqlparser lib.

Now it seems spring-data-jdbc requires jsqlparser 4.6 while spring-data-jpa requires jsqlparser 4.9 as seen here

https://mvnrepository.com/artifact/org.springframework.data/spring-data-relational/3.3.0

https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa/3.3.0

Any idea about how to fix this issue ?

Nowheresly commented 3 weeks ago

For the sake of completeness, I have added this dependency in my pom.xml:

        <dependency>
            <groupId>com.github.jsqlparser</groupId>
            <artifactId>jsqlparser</artifactId>
            <version>4.9</version>
        </dependency>

By forcing the version of jsqlparser, the jpa error is now gone. Yet I'm not sure if the jdbc part will work with no regressions...

mp911de commented 3 weeks ago

Jsqlparser is a test-only dependency, the fix will come via spring-projects/spring-data-relational#1796. Until then, either exclude the JDBC dependency or pin the dependency version, please.