Spring数据Jpa findTop和findFirst生成错误'@P0'附近的语法不正确

Posted

技术标签:

【中文标题】Spring数据Jpa findTop和findFirst生成错误\'@P0\'附近的语法不正确【英文标题】:Spring data Jpa findTop and findFirst generating error Incorrect syntax near '@P0'Spring数据Jpa findTop和findFirst生成错误'@P0'附近的语法不正确 【发布时间】:2015-09-08 09:08:09 【问题描述】:

我正在使用 Spring Data JPA 1.8.2 并试图获得最佳结果。我正在使用以下方法

LearningSession findTopBySourceAndExternalLmsSessionIdAndCourseCodeAndLearnerEnrollmentEnrollmentStatusOrderByIdAsc(String source, String externalLmsSessionId, String courseCode, String enrollmentStatus);

我也尝试删除 OrderBy

LearningSession findTopBySourceAndExternalLmsSessionIdAndCourseCodeAndLearnerEnrollmentEnrollmentStatus(String source, String externalLmsSessionId, String courseCode, String enrollmentStatus);

在这两种情况下,hibernate 都会生成以下查询。只需使用* 即可。求下单order by learningse0_.id asc

select TOP ?  learningse0_.*
from LearningSession learningse0_ 
left outer join LearnerEnrollment learnerenr1_ on learningse0_.ENROLLMENT_ID=learnerenr1_.id 
where learningse0_.source=?
and learningse0_.externalLmsSessionId=?
and learningse0_.courseCode=?
and learnerenr1_.enrollmentStatus=?

查询是正确的,但我得到以下异常

Hibernate: select TOP ?  learningse0_.id as id1_47_, learningse0_.brandName as brandNam2_47_, learningse0_.courseApprovalId as courseAp3_47_, learningse0_.courseCode as courseCo4_47_, learningse0_.endTime as endTime5_47_, learningse0_.externalLmsSessionId as external6_47_, learningse0_.externalLmsUrl as external7_47_, learningse0_.isCourseMessageDisplay as isCourse8_47_, learningse0_.LANGUAGE_ID as LANGUAG15_47_, learningse0_.LEARNER_ID as LEARNER16_47_, learningse0_.ENROLLMENT_ID as ENROLLM17_47_, learningse0_.learningSessionGuid as learning9_47_, learningse0_.lmsProvider as lmsProv10_47_, learningse0_.redirectUrl as redirec11_47_, learningse0_.source as source12_47_, learningse0_.startTime as startTi13_47_, learningse0_.uniqueUserGuid as uniqueU14_47_ from LearningSession learningse0_ left outer join LearnerEnrollment learnerenr1_ on learningse0_.ENROLLMENT_ID=learnerenr1_.id where learningse0_.source=? and learningse0_.externalLmsSessionId=? and learningse0_.courseCode=? and learnerenr1_.enrollmentStatus=? order by learningse0_.id asc
13:53:47.686 [main] DEBUG org.hibernate.engine.jdbc.spi.SqlExceptionHelper - could not extract ResultSet [n/a]
com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near '@P0'          
com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216) ~[sqljdbc4-4.0.jar:?]

我做错了什么?我试过FirstTop1First1,但结果是错误的。请帮忙。

谢谢

【问题讨论】:

您是否尝试使用@Query(...) 注释?我认为这会简化很多。 嗯我试过了。但我认为我不能像在 JPA select top 1 .. 中那样做。最后,我使用@Query 使用本机查询,现在一切正常,但关键是这种方法有什么问题。它正在生成正确的查询,但出现异常...Do I need to extends my Repository with Paging or Sorting provided by Spring-Data-JPa ? 目前我的存储库仅扩展 CrudRepository。 JpaRepository 扩展了我相信的所有这些。我唯一能想到的是它可能是一个案例问题或拼写相关。它很长,对我来说比带注释的查询更难维护。 【参考方案1】:

不确定这是否适合您,但我遇到了同样的错误,经过大量挖掘后,我发现我在 JpaVendorAdapter 中使用了 SqlServerDialect,当我将其更改为更专门用于 SqlServer2012(SqlServerDialect2012 ) 错误消失了:

<bean id="jpaVendorAdapter"
    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    <property name="database" value="SQL_SERVER" />
    <property name="databasePlatform" value="org.hibernate.dialect.SQLServer2012Dialect" />
    <property name="showSql" value="true" />
</bean>

【讨论】:

非常感谢。当我在 Spring 更新中遇到这个问题时,这正是我所需要的。【参考方案2】:

我在使用 Hibernate 5 + Spring Data 时遇到了同样的问题。 将方言更改为 SQLServer2012方言对我有用。

公共类 SQLServerNativeDialect 扩展 SQLServer2012Dialect

供参考:: https://hibernate.atlassian.net/browse/HHH-10032

谢谢,

【讨论】:

以上是关于Spring数据Jpa findTop和findFirst生成错误'@P0'附近的语法不正确的主要内容,如果未能解决你的问题,请参考以下文章

使用 RepositoryItemReader 和 Repository Item writer 的 spring 数据 JPA 的 spring 批处理

JPA Hibernate jpa spring data jpa

使用 spring-data-jpa 和 spring-mvc 过滤数据库行

Spring Boot 的数据访问:JPA 和 MyBatis

Spring数据休息和jpa @OneToMany重复“_links”

spring boot JPA 和 数据库连接