2016-11-25 5 views
4

나는 봄 4.2.4에서 다음 쿼리를 실행하려고 :왜 페이지 네비게이션을 사용하는 spring nativeQuery가 SQLGrammarException을 던집니까?

@Query(value="SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY i.TYPE_NUMBER ASC) AS RN, i.* FROM Item i) AS g WHERE RN between ?#{ #pageable.offset} and ?#{#pageable.offset + #pageable.pageSize}", 
     countQuery="SELECT count(i.ID) FROM Item i", 
    nativeQuery = true) 
Page<Item> getItems(Pageable pageable); 

이 코드는 예를 들어 여기에 보여 다음 : https://github.com/spring-projects/spring-data-jpa/blob/master/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java#L539 이것은 SQLGrammarException 결과

:

Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet 
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:123) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:91) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.loader.Loader.getResultSet(Loader.java:2066) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1863) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1839) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.loader.Loader.doQuery(Loader.java:910) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:355) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.loader.Loader.doList(Loader.java:2554) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.loader.Loader.doList(Loader.java:2540) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2370) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.loader.Loader.list(Loader.java:2365) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:353) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:1909) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.internal.AbstractSessionImpl.list(AbstractSessionImpl.java:311) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.internal.SQLQueryImpl.list(SQLQueryImpl.java:141) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:573) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:449) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final] 
    at org.springframework.data.jpa.repository.query.JpaQueryExecution$PagedExecution.doExecute(JpaQueryExecution.java:191) ~[spring-data-jpa-1.9.4.RELEASE.jar:?] 
    at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:78) ~[spring-data-jpa-1.9.4.RELEASE.jar:?] 
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:100) ~[spring-data-jpa-1.9.4.RELEASE.jar:?] 
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:91) ~[spring-data-jpa-1.9.4.RELEASE.jar:?] 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:462) ~[spring-data-commons-1.11.4.RELEASE.jar:?] 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:440) ~[spring-data-commons-1.11.4.RELEASE.jar:?] 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61) ~[spring-data-commons-1.11.4.RELEASE.jar:?] 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) ~[spring-tx-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) ~[spring-tx-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.2.6.RELEASE.jar:4.2.6.RELEASE] 

이를

com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near ','. 
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216) ~[sqljdbc4.jar:?] 
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1515) ~[sqljdbc4.jar:?]... 
에 의해 caused입니다.

페이지 매김없이 동일한 기본 쿼리를 실행하려고 시도했지만 오류없이 실행됩니다. 쿼리는 다음과 같습니다.

@Query(value="SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY i.TYPE_NUMBER ASC) AS RN, i.* FROM Item i) AS g WHERE RN between 0 and 50", 
     nativeQuery = true) 
    List<Item> getItems(); 

여기가 봄 데이터의 한계입니까? 아니면 여기에 누락 된 부분이 있습니까?

+0

'SQLGrammarException'에'원인 '이 있습니까? –

+1

예, 원인은 다음과 같습니다. '작성자 : com.microsoft.sqlserver.jdbc.SQLServerException :', '근처의 구문이 잘못되었습니다. 이것은 Pageable 객체를 사용하여 실행될 때만 발생합니다. –

+1

실행 된 SQL을 보려면 SQL 로그를 활성화하십시오. http://stackoverflow.com/documentation/hibernate/3548/enable-disable-sql-log#t=201611260820368460879 –

답변

0

스프링 데이터의 버그라고 생각합니다. 쿼리에 ORDER BY이 있으면 스프링 데이터에 , i.itemCategory asc이 추가됩니다. 다른 경우에 스프링 데이터는 ORDER BY i.itemCategory asc을 추가합니다. 이 문제를 해결하려면 ORDER BY 1=1을 쿼리에 추가하면됩니다.

@Query(value="SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY i.TYPE_NUMBER ASC) AS RN, i.* FROM Item i) AS g WHERE RN between ?#{ #pageable.offset} and ?#{#pageable.offset + #pageable.pageSize}, ORDER BY 1=1", 
     countQuery="SELECT count(i.ID) FROM Item i", 
    nativeQuery = true) 
Page<Item> getItems(Pageable pageable);