JPQL प्रश्नों के लिए समाधान
यह भीतर 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();
}
महत्वपूर्ण लेख
- पैकेज नाम सहित बीन क्लास के लिए पूरी तरह से योग्य पथ प्रदान करना सुनिश्चित करें। उदाहरण के लिए, अगर बीन क्लास कहा जाता है
MyBean
और यह पैकेज में है com.path.to
, तो बीन के लिए पूरी तरह से योग्य रास्ता होगा com.path.to.MyBean
। बस प्रदान करने MyBean
से काम नहीं चलेगा (जब तक कि बीन क्लास डिफ़ॉल्ट पैकेज में न हो)।
new
कीवर्ड का उपयोग करके बीन क्लास कंस्ट्रक्टर को कॉल करना सुनिश्चित करें । SELECT new com.path.to.MyBean(...)
काम करेंगे, जबकि SELECT com.path.to.MyBean(...)
नहीं करेंगे।
- बीन कंस्ट्रक्टर में अपेक्षित रूप से उसी क्रम में विशेषताएँ पास करना सुनिश्चित करें। एक अलग क्रम में विशेषताओं को पारित करने का प्रयास एक अपवाद का कारण होगा।
- सुनिश्चित करें कि क्वेरी एक वैध JPA क्वेरी है, यानी यह एक देशी क्वेरी नहीं है।
@Query("SELECT ...")
, या @Query(value = "SELECT ...")
, या @Query(value = "SELECT ...", nativeQuery = false)
काम करेगा, जबकि @Query(value = "SELECT ...", nativeQuery = true)
काम नहीं करेगा। इसका कारण यह है कि देशी प्रश्नों को जेपीए प्रदाता के संशोधनों के बिना पारित किया जाता है, और अंतर्निहित आरडीबीएमएस के खिलाफ निष्पादित किया जाता है। के बाद से new
और com.path.to.MyBean
वैध एसक्यूएल कीवर्ड नहीं हैं, आरडीबीएमएस तो एक अपवाद फेंकता है।
देशी प्रश्नों का हल
जैसा कि ऊपर उल्लेख किया गया है, new ...
वाक्यविन्यास एक जेपीए समर्थित तंत्र है और सभी जेपीए प्रदाताओं के साथ काम करता है। हालाँकि, यदि क्वेरी स्वयं एक JPA क्वेरी नहीं है, अर्थात, यह एक देशी क्वेरी है, तो new ...
सिंटैक्स काम नहीं करेगा क्योंकि क्वेरी सीधे अंतर्निहित RDBMS पर पारित हो जाती है, जो new
कीवर्ड को नहीं समझती है क्योंकि यह इसका हिस्सा नहीं है एसक्यूएल मानक।
इन जैसी स्थितियों में, बीन वर्गों को स्प्रिंग डेटा प्रोजेक्शन इंटरफेस के साथ बदलने की आवश्यकता होती है ।
चरण 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();
}
AS
परिणामी क्षेत्रों को मैप करने के लिए SQL मैप का उपयोग करें ।
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..........