2012-01-06 17 views
11

मैं ग्लासफ़िश और जेएसएफ का उपयोग कर अपना पहला जावा ईई वेब एप्लिकेशन बना रहा हूं। मैं मानदंड क्वेरी के लिए बिल्कुल नया हूं और मेरे पास एक क्वेरी है जो मुझे करने की ज़रूरत है लेकिन javaee6 ट्यूटोरियल उदाहरणों पर थोड़ा पतला लगता है। वैसे भी, मुझे क्वेरी बनाने में कठिनाई हो रही है।जेपीए मानदंड क्वेरी बनाने में मदद की ज़रूरत है

लक्ष्य: मैं कंपनी को संग्रहीत अधिकांश दस्तावेज़ों के साथ खींचना चाहता हूं। कंपनियां दस्तावेज़ों के साथ एक बहुत ही रिश्तेदार हैं। दस्तावेज़ों में कई तालिकाओं के साथ बहुत से संबंध हैं, "usertype" कॉलम उन्हें अलग करता है।

MySQL क्वेरी:

 CriteriaBuilder cb = em.getCriteriaBuilder(); 
     CriteriaQuery<Documents> cqry = cb.createQuery(Documents.class); 
     //Intersting Stuff 
     Root<Documents> root = cqry.from(Documents.class); 
     Expression userid = root.get("userID"); 
     Expression usertype = root.get("userType"); 
     Expression count = cb.count(userid); 
     cqry.multiselect(userid, count); 
     Predicate userType = cb.equal(usertype, "COMPANY"); 
     cqry.where(userType); 
     cqry.groupBy(userid); 
     cqry.orderBy(cb.desc(count)); 
     //more boilerplate 
     Query qry = em.createQuery(cqry); 
     List<Documents> results = qry.getResultList(); 

त्रुटि मैं मिलता है:

SELECT USERID, COUNT(USERID) AS CNT 
FROM DOCUMENTS 
WHERE USERTYPE="COMPANY" 
GROUP BY USERID 
ORDER BY CNT DESC 

धन्यवाद

--update-- प्रयोक्ताओं की राय के आधार पर, यहाँ क्या मैं अब तक किया है :

Exception Description: Partial object queries are not allowed to maintain the cache or be edited. You must use dontMaintainCache(). 

विशिष्ट त्रुटि, मेरे लिए कुछ भी नहीं है!

+0

एपीआई को अपमानित किए बिना गिनती का चयन करने के लिए CriteriaQuery से CriteriaQuery से क्वेरी को डी-टाइप करने का प्रयास करें। यदि आप टेबल/इकाइयों के बारे में अधिक जानकारी पोस्ट करते हैं तो मैं कुछ अन्य तरीकों का प्रयास कर सकता हूं – perissf

उत्तर

20

आपकी क्वेरी में पूरा इकाई वस्तु वापस नहीं करता है के रूप में आप केवल दी गई सारणी के दो क्षेत्रों का चयन कर रहे हैं (यही कारण है कि आप एक त्रुटि है कि कहते हैं yadayadapartialyadayada हो रही है)।

आपका समाधान लगभग सही है, इसे बनाने के लिए आपको इसे बदलने की आवश्यकता है, इसे आंशिक

एक सादे CriteriaQuery<...> आप CriteriaBuilder.createTupleQuery() को फोन करके एक टपल CriteriaQuery<..> बनाने के लिए करने के बजाय

। (मूल रूप से, आप CriteriaBuilder.createQuery(...) कॉल कर सकते हैं और एक तर्क के रूप में यह करने के लिए Tuple.class गुजरती हैं। Tupleवाइल्डकार्ड इकाई वर्ग का एक प्रकार है।)

CriteriaBuilder cb = em.getCriteriaBuilder(); 
CriteriaQuery<Tuple> cq= cb.createTupleQuery(); 

Root<Documents> root = cq.from(Documents.class); 
Expression<Integer> userId = root.get("USERID"); 
Expression<String> userType = root.get("USERTYPE"); 
Expression<Long> count = cb.count(userId); 

cq.multiselect(userId.alias("USERID"), count.alias("CNT")); 
cq.where(cb.equal(userType, "COMPANY"); 
cq.groupBy(userId); 
cq.orderBy(cb.desc(count)); 

TypedQuery<Tuple> tq = em.createQuery(cq); 
for (Tuple t : tq.getResultsList()) { 
    System.out.println(t.get("USERID")); 
    System.out.println(t.get("CNT")); 
} 

(एक Tuple की एक्सेस करना क्षेत्रों अगर मैं 'नहीं था मुझे एक त्रुटि दे दी है टी उपयोग उन्हें के प्रचलित नाम (multiselect(...) में)। यही कारण है कि मैं उपनाम का उपयोग किया है, लेकिन इस और अधिक सफाई से जेपीए 2 के Metamodel एपीआई, जो विनिर्देश में वर्णित है काफी अच्छी तरह से उपयोग करके घेरने की कोशिश की जा सकती है।)

के लिए प्रलेखन CriteriaQuery.multiselect(...)Tuple ऑब्जेक्ट्स का उपयोग करके क्वेरी के व्यवहार का वर्णन अधिक गहराई से करता है।

+0

शानदार! यह बॉक्स के ठीक बाहर के साथ काम किया। इस और लेख @Mechkov साझा के बीच में मुझे मानदंड प्रश्नों की एक बेहतर समझ है। धन्यवाद। –

+0

अच्छा जवाब, निम्नलिखित त्रुटि के साथ मेरी समस्या को हल करने में मदद मिली 'आपको अपने कोड उदाहरण के लिए धन्यवाद dontMaintainCache() ' – user75ponic

+0

का उपयोग करना होगा। मैंने इसके साथ tuples (संस्थाओं के बजाय) का उपयोग कर जेपीए मानदंड प्रश्नों के बारे में बहुत कुछ सीखा है। – hbobenicio

0

इस आसान ट्यूटोरियल में एक नज़र डालें। यह JPA2 और मानदंड

http://www.jumpingbean.co.za/blogs/jpa2-criteria-api

सादर का उपयोग करता है!

+1

आपके द्वारा पोस्ट किया गया ट्यूटोरियल ठीक है, लेकिन ओपी चाहता है कि एक दिलचस्प सवाल उठाए: प्रश्न मानदंड एपीआई वास्तव में उपयोगी होता है जब क्वेरी अलग-अलग ऑब्जेक्ट देता है प्रकार? – perissf

+0

धन्यवाद, ट्यूटोरियल ने मुझे बहुत मदद की। जहां तक ​​मुझे विभिन्न प्रकार की जरूरत है, आईडी (लंबी) है। –

+0

कूल। खुशी हुई यह मदद की। मैंने इसे बहुत पहले इस्तेमाल किया, बहुत पहले नहीं। – Mechkov

2

आप हाइबरनेट का उपयोग कर रहे हैं, तो यह काम करना चाहिए:

ProjectionList pl = Projections.projectionList() 
.add(Projections.groupProperty("userid")) 
.add(Projections.property("userid")) 
.add(Projections.count("userid")); 

Criteria criteria = session.createCriteria(Document.class) 
.add(Restrictions.eq("usertype",usertype)) 
.setProjection(pl) 
.addOrder(Order.desc("cnt")); 

आशा है कि यह मदद करता है!

+0

इसका मतलब है हाइबरेट का उपयोग करना, जो यहां दायरे से बाहर है। आपको कम से कम इसका जिक्र करना चाहिए। – perissf

+0

हाँ, मुझे डर है कि मैं हाइबरनेट का उपयोग नहीं कर रहा हूं। यद्यपि मैं चाहता हूं कि मैं चाहता हूं! –

+0

ओह, बड़ी माफ़ी। उसे एहसास नहीं हुआ! – Gonzalo

संबंधित मुद्दे