首页 > 解决方案 > Spring Data 和 SQL Server 在关键字“as”错误附近出现语法错误

问题描述

我正在尝试使用 Spring Data 从 SQL Server 表中读取数据。我有可以正常工作的本机查询,但我想改用 Spring Repository 和 find() 方法。

我定义了一个实体:

@Entity
@Table(name = "my table")
// This native query works when I try and use it.
@NamedNativeQuery(name = "Associate.getDistinctBusinessUnits",
    query = "SELECT DISTINCT bus_unit_name FROM \"my table\" ORDER BY bus_unit_name"
)
public class Associate {
    @Id
    @Column(name = "assoc_oper_id", columnDefinition = "VARCHAR(50)")
    public String assocOperId;

...
}

和一个存储库

@Repository
public interface AssociateRepository extends PagingAndSortingRepository<Associate, String> {
    List<String> getDistinctBusinessUnits();
}

我的控制器正在调用存储库

// This query fails.
final Optional<Associate> result = associateRepository.findById(associateId);

但是当我得到

12147 [http-nio-8080-exec-1] ERROR o.h.e.jdbc.spi.SqlExceptionHelper - Incorrect syntax near the keyword 'as'.
12181 [http-nio-8080-exec-1] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [/roster-service] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause
com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near the keyword 'as'.
        at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:256)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1621)
        at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:592)
        at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:522)
        at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7194)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:2930)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:248)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:223)
        at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeQuery(SQLServerPreparedStatement.java:444)
        at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52)
        at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java)
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:60)
        at org.hibernate.loader.Loader.getResultSet(Loader.java:2167)
        at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1930)
        at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1892)
        at org.hibernate.loader.Loader.doQuery(Loader.java:937)
        at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:340)
        at org.hibernate.loader.Loader.doList(Loader.java:2689)
        at org.hibernate.loader.Loader.doList(Loader.java:2672)
        at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2506)
        at org.hibernate.loader.Loader.list(Loader.java:2501)
        at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:504)
        at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:395)
        at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:220)
        at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1508)
        at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1537)
        at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1505)
        at org.hibernate.query.Query.getResultList(Query.java:135)
        at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:74)
        at org.springframework.data.jpa.repository.support.SimpleJpaRepository.readPage(SimpleJpaRepository.java:569)
        at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:388)
        at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:356)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:359)
        at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:644)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:608)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
        at com.sun.proxy.$Proxy119.findAll(Unknown Source)
        at com.cerner.abilities.roster.service.controllers.AssociatesController.getAssociates(AssociatesController.java:59)
        at com.cerner.abilities.roster.service.controllers.AssociatesController$$FastClassBySpringCGLIB$$a1313748.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
        at com.my.project.controllers.AssociatesController$$EnhancerBySpringCGLIB$$34fe814.getAssociates(<generated>)

我知道我的数据库连接工作正常,因为我的本机查询存储库方法按预期工作。我已经尝试了几种不同风格的现有 Repository 方法以及我定义的方法来尝试得到相同的错误。

我的弹簧配置是

# ===============================
# DATABASE
# ===============================

spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.url=jdbc:sqlserver://grddwmrtwhqipdw.northamerica.cerner.net:1433;databaseName=IPDW_PROD02
spring.datasource.username=ablab
spring.datasource.password=ablab


# ===============================
# JPA / HIBERNATE
# ===============================

spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServerDialect

我将 Spring Boot 2.1.3 与 Spring Data 2.1.5 一起使用(我确实尝试了 Spring Data 2.1.3,以防它们需要同步),我相信这是当前可用的最新版本。

我不拥有数据库服务器,也不知道如何从 SQL 明确检查版本,但我尝试了几种不同的方言。我也不知道哪里有一个司机所有可用方言的明确列表,所以我不知道我是否都试过了。

我对 Spring 和 Spring Data 的经验并不丰富。我已经以类似的方式针对 Oracle 使用了存储库,没有问题,所以我的猜测是 SqlServer 的一个特性。

任何人都有一些想法从这里去哪里?

谢谢!!

标签: sql-serverspringspring-bootspring-data

解决方案


@Table(name = "my table") 应该是 @Table(name = "`my table`")


推荐阅读