2012-02-25 12 views
34

में दिनांक इकाइयों की तुलना करें EclipseLink कार्यान्वयन के साथ जेपीए 2 का उपयोग करना।जेपीए मानदंड एपीआई

मैं एक गतिशील क्वेरी बनाने की कोशिश कर रहा हूं जो मुझे किसी दिए गए दिनांक के बाद कुछ रिकॉर्ड जारी रखे।

CriteriaBuilder builder = em.getCriteriaBuilder(); 
CriteriaQuery<Event> criteria = builder.createQuery(Event.class); 
Root<Event> root = criteria.from(Event.class); 
criteria.select(root); 
criteria.distinct(true); 
List<Predicate> predicates = new ArrayList<Predicate>(); 
//... 
if (dateLimit != null){ 
    ParameterExpression<Date> param = builder.parameter(Date.class, "dateLimit"); 
    predicates.add(builder.lessThanOrEqualTo(root.get("dateCreated"), param)); 
} 

lessThanOrEqualTo() और le() जो मुझे इस मामले में मदद मिल सकती है की तरह लग रहे एपीआई में केवल दो तरीके हैं। यह चेतावनी ग्रहण हालांकि द्वारा फेंका जाता है:

Bound mismatch: The generic method lessThanOrEqualTo(Expression<? extends Y>, Expression<? extends Y>) 
of type CriteriaBuilder is not applicable for the arguments (Path<Object>, ParameterExpression<Date>). 
The inferred type Object is not a valid substitute for the bounded parameter 
<Y extends Comparable<? super Y>> 

मैं कल्पना कर सकते हैं कि मैं इस समस्या के लिए सही दृष्टिकोण नहीं ले रहा हूँ, लेकिन मैं एक संभव समाधान के लिए कहीं भी कुछ सुझाव या संकेत नहीं मिल रहा।

उत्तर

58

समस्या यह है कि स्ट्रिंग-आधारित API के साथ यह get -Operation के परिणाम मान के प्रकार को अनुमानित नहीं कर सकता है। उदाहरण के लिए यह Javadoc for Path में समझाया गया है।

आप के बजाय

predicates.add(builder.lessThanOrEqualTo(root.<Date>get("dateCreated"), param)); 

का उपयोग करते हैं, यह ठीक से काम, क्योंकि यह प्रकार तर्क से वापसी प्रकार पता लगा सकते हैं और यह पता लगाना होगा कि यह तुलनीय है जाएगा। नोट, पैरामीटरयुक्त विधि आमंत्रण का उपयोग root.<Date>get(...) (देखें, उदाहरण के लिए, When is a parameterized method call useful?)।

एक और (मेरी राय में बेहतर) समाधान स्ट्रिंग-आधारित एक के बजाय मेटामोडेल आधारित API का उपयोग करना है। कैनोलिक मेटामोडेल के बारे में एक साधारण उदाहरण उदाहरण के लिए here दिया गया है। यदि आपके पास निवेश करने के लिए अधिक समय है, तो यह स्थिर मेटामोडेल के बारे में एक अच्छा लेख है: Dynamic, typesafe queries in JPA 2.0

+1

नेटबीन 8.2 अभी भी मानदंडों के साथ चेतावनी देता है। मुझे नहीं पता क्यों। 'builder.greaterThanOrEqualsTo (root.get (Some_.date), दिनांक)' <> 'builder.greaterThanOrEqualsTo (रूट। प्राप्त करें (कुछ_.date), दिनांक)' –

+0

@ जिन क्वॉन: 'javax.persistence आयात करना सुनिश्चित करें .criteria.Predicate', 'java.util.function.Predicate' नहीं। यह मेरे लिए तय है :) – Hank

+0

एक खराब आयात मुद्दा नहीं है, यह एक बग है, एक बहुत पुराना है। कार्य करने के लिए आपको इसे एक चर के रूप में घोषित करना होगा और इसे पैरामीटर के रूप में उपयोग करना होगा: 'पथ पथ = root.get (.....); builder.greaterThan (पथ, तारीख); ' – FiruzzZ

12

गुणों तक पहुंचने के लिए जेनरेट किए गए मेटामोडेल का उपयोग करने की आवश्यकता है, यह वास्तव में एक सुरक्षित तरीका है।

Path<Date> dateCreatedPath = root.get("dateCreated"); 
predicates.add(builder.lessThanOrEqualTo(dateCreatedPath, dateLimit)); 
1

: यदि आप अपने गुण का उल्लेख करने के तार का उपयोग करते हैं, प्रकार केवल जब विधि बुला, या एक प्रकार कलाकारों द्वारा, या संकलक द्वारा किया स्वत: प्रकार निष्कर्ष द्वारा इस्तेमाल किया स्पष्ट सामान्य प्रकार से निष्कर्ष निकाला जा सकता है मुझे एक समान त्रुटि मिल रही थी लेकिन वाक्यविन्यास predicates.add(cb.greaterThan(article.get(Article_.created), since)); के साथ और यह पृष्ठ मिला। मेरे लिए कारण यह साबित हुआ कि मैंने जावा प्रोजेक्ट को जावा 1.7 से 1.8 तक अपग्रेड किया था, और इस प्रक्रिया में मैवेन को जावा 1.8 के लिए संकलित करने के लिए कॉन्फ़िगर किया गया था। त्रुटि को ठीक करने के लिए, मुझे बाकी परियोजना को 1.8 पर रखते हुए मैवेन कंपाइल को 1.7 पर वापस बदलना पड़ा।

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