JPQL 쿼리 솔루션
이것은 JPA 사양 내의 JPQL 쿼리에 대해 지원됩니다 .
1 단계 : 간단한 빈 클래스 선언
package com.path.to;
public class SurveyAnswerStatistics {
private String answer;
private Long cnt;
public SurveyAnswerStatistics(String answer, Long cnt) {
this.answer = answer;
this.count = cnt;
}
}
2 단계 : 저장소 메서드에서 빈 인스턴스 반환
public interface SurveyRepository extends CrudRepository<Survey, Long> {
@Query("SELECT " +
" new com.path.to.SurveyAnswerStatistics(v.answer, COUNT(v)) " +
"FROM " +
" Survey v " +
"GROUP BY " +
" v.answer")
List<SurveyAnswerStatistics> findSurveyCount();
}
중요 사항
- 패키지 이름을 포함하여 Bean 클래스에 대한 완전한 경로를 제공해야합니다. 예를 들어, Bean 클래스가 호출
MyBean
되고 package com.path.to
에있는 경우 Bean에 대한 완전한 경로는입니다 com.path.to.MyBean
. 단순히 제공하는 MyBean
것은 작동하지 않습니다 (빈 클래스가 기본 패키지에 있지 않는 한).
new
키워드를 사용하여 Bean 클래스 생성자를 호출해야 합니다. SELECT new com.path.to.MyBean(...)
작동하지만 작동 SELECT com.path.to.MyBean(...)
하지 않습니다.
- Bean 생성자에서 예상 한 것과 정확히 동일한 순서로 속성을 전달해야합니다. 다른 순서로 속성을 전달하려고하면 예외가 발생합니다.
- 쿼리가 유효한 JPA 쿼리인지, 즉 기본 쿼리가 아닌지 확인하십시오.
@Query("SELECT ...")
, 또는 @Query(value = "SELECT ...")
, 또는 @Query(value = "SELECT ...", nativeQuery = false)
작동하지만 @Query(value = "SELECT ...", nativeQuery = true)
작동하지 않습니다. 이는 기본 쿼리가 JPA 공급자에 대한 수정없이 전달되고 기본 RDBMS에 대해 실행되기 때문입니다. 이후 new
및 com.path.to.MyBean
유효한 SQL 키워드 아니다는 RDBMS는 예외가 발생합니다.
네이티브 쿼리를위한 솔루션
위에서 언급했듯이 new ...
구문은 JPA 지원 메커니즘이며 모든 JPA 공급자와 함께 작동합니다. 그러나, 즉, 네이티브 쿼리가 JPA 쿼리하지 쿼리 자체 인 경우, new ...
구문은 쿼리로하지 작업은 이해하지 못하는 기본 RDBMS에 직접 전달되는 것 new
이 부분이 아니기 때문에 키워드 SQL 표준.
이와 같은 상황에서는 빈 클래스를 SpringData Projection 인터페이스 로 대체해야합니다 .
1 단계 : 프로젝션 인터페이스 선언
package com.path.to;
public interface SurveyAnswerStatistics {
String getAnswer();
int getCnt();
}
2 단계 : 쿼리에서 프로젝션 된 속성 반환
public interface SurveyRepository extends CrudRepository<Survey, Long> {
@Query(nativeQuery = true, value =
"SELECT " +
" v.answer AS answer, COUNT(v) AS cnt " +
"FROM " +
" Survey v " +
"GROUP BY " +
" v.answer")
List<SurveyAnswerStatistics> findSurveyCount();
}
SQL AS
키워드를 사용하여 결과 필드를 명확한 매핑을 위해 프로젝션 속성에 매핑합니다.
Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Unable to locate class [SurveyAnswerReport] [select new SurveyAnswerReport(v.answer,count(v.id)) from com.furniturepool.domain.Survey v group by v.answer] at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1750) at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677) at org.hibernate.jpa.spi.AbstractEnti..........