JPQL sorguları için çözüm
Bu, JPA spesifikasyonu dahilindeki JPQL sorguları için desteklenir .
1. Adım : Basit bir fasulye sınıfı bildirin
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. Adım : Kod deposu yönteminden fasulye örneklerini iade edin
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();
}
Önemli notlar
- Paket adı dahil olmak üzere, fasulye sınıfının tam yolunu sağladığınızdan emin olun. Örneğin, fasulye sınıfı çağrılırsa
MyBean
ve com.path.to
paketteyse, çekirdeğe giden tam nitelikli yol olacaktır com.path.to.MyBean
. Basitçe sağlamak MyBean
işe yaramayacaktır (bean sınıfı varsayılan pakette değilse).
new
Anahtar kelimeyi kullanarak bean sınıfı yapıcısını çağırdığınızdan emin olun . SELECT new com.path.to.MyBean(...)
çalışacak, oysa SELECT com.path.to.MyBean(...)
olmayacak.
- Öznitelikleri, bean yapıcısında beklenen sırayla tam olarak aynı sırada geçirdiğinizden emin olun. Öznitelikleri farklı bir sırayla geçirmeye çalışmak bir istisnaya yol açar.
- Sorgunun geçerli bir JPA sorgusu olduğundan, yani yerel bir sorgu olmadığından emin olun.
@Query("SELECT ...")
, veya @Query(value = "SELECT ...")
veya @Query(value = "SELECT ...", nativeQuery = false)
çalışacak, oysa @Query(value = "SELECT ...", nativeQuery = true)
çalışmayacak. Bunun nedeni, yerel sorguların JPA sağlayıcısında değişiklik yapılmadan geçirilmesi ve bu şekilde temeldeki RDBMS'ye karşı yürütülmesidir. Yana new
ve com.path.to.MyBean
geçerli bir SQL anahtar olmayan, RDBMS sonra bir istisna atar.
Yerel sorgular için çözüm
Yukarıda belirtildiği gibi new ...
sözdizimi, JPA destekli bir mekanizmadır ve tüm JPA sağlayıcılarıyla çalışır. Bununla birlikte, sorgunun kendisi bir JPA sorgusu değilse, yani yerel bir sorgu ise, new ...
sözdizimi, sorgu doğrudan temeldeki RDBMS'ye iletildiği için çalışmayacaktır, bu da new
anahtar kelimeyi anlamıyor çünkü SQL standardı.
Bu gibi durumlarda, fasulye sınıflarının Spring Data Projection arabirimleriyle değiştirilmesi gerekir .
1. Adım : Bir projeksiyon arayüzü bildirin
package com.path.to;
public interface SurveyAnswerStatistics {
String getAnswer();
int getCnt();
}
Adım 2 : Sorgudan öngörülen özellikleri iade edin
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();
}
AS
Kesin haritalama için sonuç alanlarını projeksiyon özellikleriyle eşlemek için SQL anahtar sözcüğünü kullanın .
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..........