웹 프로젝트에서 MySQL 5.6 데이터베이스와 함께 최신 스프링 데이터 (1.10.2)를 사용하여 페이지 매김과 함께 네이티브 쿼리를 사용하려고하지만 org.springframework.data.jpa.repository.query.InvalidJpaQueryMethodException
시작할 때 발생합니다.
업데이트 : 20180306이 문제는 이제 Spring 2.0.4 에서 수정되었습니다. 여전히 이전 버전에 관심이 있거나 이전 버전을 사용하는 경우 관련 답변과 주석에서 해결 방법을 확인하십시오.
Spring-data 문서에서 @Query 사용의 Example 50에 따르면 다음 과 같이 쿼리 자체와 countQuery를 지정할 수 있습니다.
public interface UserRepository extends JpaRepository<User, Long> {
@Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1",
countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",
nativeQuery = true)
Page<User> findByLastname(String lastname, Pageable pageable);
}
호기심으로 NativeJpaQuery
수업 중에 유효한 jpa 쿼리인지 확인하는 다음 코드가 포함되어 있음을 알 수 있습니다.
public NativeJpaQuery(JpaQueryMethod method, EntityManager em, String queryString, EvaluationContextProvider evaluationContextProvider, SpelExpressionParser parser) {
super(method, em, queryString, evaluationContextProvider, parser);
JpaParameters parameters = method.getParameters();
boolean hasPagingOrSortingParameter = parameters.hasPageableParameter() || parameters.hasSortParameter();
boolean containsPageableOrSortInQueryExpression = queryString.contains("#pageable") || queryString.contains("#sort");
if(hasPagingOrSortingParameter && !containsPageableOrSortInQueryExpression) {
throw new InvalidJpaQueryMethodException("Cannot use native queries with dynamic sorting and/or pagination in method " + method);
}
}
내 쿼리에는 Pageable
매개 변수 가 포함되어 있으므로 hasPagingOrSortingParameter
도 true
있지만 제공하지 않는 에서 #pageable
또는 #sort
시퀀스를 찾고 queryString
있습니다.
#pageable
쿼리 끝에 (주석)을 추가하여 유효성 검사를 통과했지만 쿼리에 2 대신 3이라는 추가 매개 변수가 필요하다는 메시지가 실행에 실패합니다.
재미있는 점은 실행 중에 수동으로 containsPageableOrSortInQueryExpression
에서 false
로 변경 true
하면 쿼리가 제대로 작동하므로 해당 문자열이 내 위치에 있는지 확인하는 이유를 queryString
모르고 제공하는 방법을 모릅니다.
어떤 도움이라도 대단히 감사하겠습니다.
2018
년 1 월 30 일 업데이트 Spring-Data 프로젝트의 개발자 가 Jens Schauder 의 PR 을 통해이 문제에 대한 수정 작업을하고있는 것 같습니다.
답변
미리 사과드립니다. 이것은 원래 질문과 Janar 의 의견을 거의 요약 한 것입니다 .
나는 같은 문제에 부딪혔다. 나는 SpringData의 Example 50을 페이지 매김이있는 네이티브 쿼리를 필요로하는 솔루션으로 찾았 지만 Spring은 시작할 때 네이티브 쿼리와 함께 페이지 매김을 사용할 수 없다고 불평했다.
다음 코드를 사용하여 페이지 매김을 사용하여 필요한 기본 쿼리를 성공적으로 실행했다고보고하고 싶었습니다.
@Query(value="SELECT a.* "
+ "FROM author a left outer join mappable_natural_person p on a.id = p.provenance_id "
+ "WHERE p.update_time is null OR (p.provenance_name='biblio_db' and a.update_time>p.update_time)"
+ "ORDER BY a.id \n#pageable\n",
/*countQuery="SELECT count(a.*) "
+ "FROM author a left outer join mappable_natural_person p on a.id = p.provenance_id "
+ "WHERE p.update_time is null OR (p.provenance_name='biblio_db' and a.update_time>p.update_time) \n#pageable\n",*/
nativeQuery=true)
public List<Author> findAuthorsUpdatedAndNew(Pageable pageable);
countQuery (코드 블록에서 주석 처리됨)는 Page<Author>
쿼리의 반환 유형으로 사용하는 데 필요하며, 예상 매개 변수 수에 대한 런타임 오류를 방지하기 위해 “#pageable”주석 주위에 줄 바꿈이 필요합니다 ( 해결 방법). 이 버그가 곧 수정되기를 바랍니다.
답변
이것은 버전 2.0.4 이전의 SpringData JPA를 사용하는 프로그램에 대한 해킹입니다 .
코드는 PostgreSQL 및 MySQL과 함께 작동합니다.
public interface UserRepository extends JpaRepository<User, Long> {
@Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1 ORDER BY ?#{#pageable}",
countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",
nativeQuery = true)
Page<User> findByLastname(String lastname, Pageable pageable);
}
ORDER BY ?#{#pageable}
입니다 Pageable
.
countQuery
입니다 Page<User>
.
답변
기록을 위해 H2를 테스트 데이터베이스로 사용하고 MySQL을 런타임에 사용하면이 접근 방식이 작동합니다 (예는 group의 최신 객체 임 ).
@Query(value = "SELECT t.* FROM t LEFT JOIN t AS t_newer " +
"ON t.object_id = t_newer.object_id AND t.id < t_newer.id AND o_newer.user_id IN (:user_ids) " +
"WHERE t_newer.id IS NULL AND t.user_id IN (:user_ids) " +
"ORDER BY t.id DESC \n-- #pageable\n",
countQuery = "SELECT COUNT(1) FROM t WHERE t.user_id IN (:user_ids) GROUP BY t.object_id, t.user_id",
nativeQuery = true)
Page<T> findByUserIdInGroupByObjectId(@Param("user_ids") Set<Integer> userIds, Pageable pageable);
SpringData JPA 1.10.5, H2 1.4.194, MySQL Community Server 5.7.11-log (innodb_version 5.7.11).
답변
@Lasneyx와 똑같은 증상이 있습니다. Postgres 네이티브 쿼리에 대한 해결 방법
@Query(value = "select * from users where user_type in (:userTypes) and user_context='abc'--#pageable\n", nativeQuery = true)
List<User> getUsersByTypes(@Param("userTypes") List<String> userTypes, Pageable pageable);
답변
이 시도:
public interface UserRepository extends JpaRepository<User, Long> {
@Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1 ORDER BY /*#pageable*/",
countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",
nativeQuery = true)
Page<User> findByLastname(String lastname, Pageable pageable);
}
( "/* */"
대 Oracle notation
)
답변
나는 오라클 데이터베이스를 사용하고 결과를 얻지 못했지만 d-man이 위에서 말한 생성 된 쉼표로 오류가 발생했습니다.
그런 다음 내 해결책은 다음과 같습니다.
Pageable pageable = new PageRequest(current, rowCount);
Pagable을 만들 때 순서없이 볼 수 있습니다.
그리고 DAO의 방법 :
public interface UserRepository extends JpaRepository<User, Long> {
@Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1 /*#pageable*/ ORDER BY LASTNAME",
countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",
nativeQuery = true)
Page<User> findByLastname(String lastname, Pageable pageable);
}
답변
다음 두 가지 방법 모두 네이티브 쿼리 페이지 매김을 위해 MySQL에서 잘 작동합니다. 그래도 H2에서는 작동하지 않습니다. SQL 구문 오류를 표시합니다.
- ORDER BY? # {# pageable}
- a.id로 정렬 \ n # pageable \ n
