2010-03-29 9 views
7

हमें यह सुनिश्चित करने की ज़रूरत है कि पिछले 30 दिनों के भीतर केवल जेपीक्यूएल क्वेरी के लिए परिणाम लौटाए जाएं। एक उदाहरण इस प्रकार है:जेपीए क्वेरी के साथ टाइमस्टैम्प तुलना कैसे करें?

Date now = new Date(); 
Timestamp thirtyDaysAgo = new Timestamp(now.getTime() - 86400000*30); 

Query query = em.createQuery(
    "SELECT msg FROM Message msg "+ 
    "WHERE msg.targetTime < CURRENT_TIMESTAMP AND msg.targetTime > {ts, '"+thirtyDaysAgo+"'}"); 
List result = query.getResultList();

यहाँ त्रुटि है हम प्राप्त करते हैं:

<openjpa-1.2.3-SNAPSHOT-r422266:907835 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: An error occurred while parsing the query filter 'SELECT msg FROM BroadcastMessage msg WHERE msg.targetTime < CURRENT_TIMESTAMP AND msg.targetTime > {ts, '2010-04-18 04:15:37.827'}'. Error message: org.apache.openjpa.kernel.jpql.TokenMgrError: Lexical error at line 1, column 217. Encountered: "{" (123), after : ""

मदद!

+0

टीएस क्या है? आपकी क्वेरी में ब्रैकेट क्यों हैं? {...} – Rick

+0

निम्नलिखित लिंक में दस्तावेज़ के रूप में "जेडीबीसी एस्केप सिंटैक्स" टाइमस्टैम्प शाब्दिक का उपयोग करने का प्रयास कर रहा है। ऐसा लगता है जैसे डेटा न्यूक्लियस का सुझाव एक बेहतर समाधान है। http://openjpa.apache.org/builds/latest/docs/manual/jpa_langref.html#jpa_langref_lit http://publib.boulder.ibm.com/infocenter/cscv/v10r1/topic/com.ibm.cloudscape.doc /rrefjdbc41784.html#rrefjdbc41784 – Lightbeard

+0

कोड प्राप्त करने के लिए आपको ओपनजेपीए के खिलाफ एक बग खोलना चाहिए ... या डॉक्टर तय किया गया है। – Rick

उत्तर

11

तो आपके द्वारा इनपुट की गई क्वेरी जेपीक्यूएल नहीं है (जिसे आप जेपीए स्पेक का जिक्र करके देख सकते हैं)। यदि आप किसी दिनांक के साथ किसी फ़ील्ड की तुलना करना चाहते हैं तो आप दिनांक

msg.targetTime < CURRENT_TIMESTAMP AND msg.targetTime > :param 

पर पैरामीटर के रूप में दिनांक इनपुट करें, यह SQL नहीं है।

+4

यह हमारे जेपीए कार्यान्वयन के लिए यहां वैध जेपीक्यूएल है: http://openjpa.apache.org/builds/latest/docs/manual/jpa_langref.html#jpa_langref_lit "जेडीबीसी एस्केप सिंटैक्स" का उपयोग करके। आपको नई तकनीक के साथ शुरू करने की कोशिश करने वाले लोगों के लिए कुछ सहानुभूति रखने पर विचार करना चाहिए। – Lightbeard

+2

हाँ, आप सही हैं; मैं भूल गया था कि आरडीबीएमएस जेपीक्यूएल कितना विशिष्ट है। जेपीए स्पेक के अनुसार, इस तरह के सिंटैक्स से बचने के लिए सलाह अभी भी होगी, आप इसे समर्थन देने वाले जेडीबीसी ड्राइवर पर निर्भर हैं, और क्वेरी वास्तव में पैरामीटर के साथ बहुत साफ है। – DataNucleus

9

जेडीबीसी एस्केप सिंटैक्स ओपनजेपीए के संस्करण में समर्थित नहीं हो सकता है जिसका आप उपयोग कर रहे हैं। नवीनतम 1.2.x रिलीज के लिए प्रलेखन यहां है: http://openjpa.apache.org/builds/1.2.2/apache-openjpa-1.2.2/docs/manual/manual.html#jpa_langref_lit

प्रलेखन पहले उल्लेख किया OpenJPA 2.0.0 के लिये दस्तावेज को संदर्भित करता है (नवीनतम): http://openjpa.apache.org/builds/latest/docs/manual/jpa_langref.html#jpa_langref_lit

कहा है कि ऐसा कोई कारण है कि आप अपने JPQL में एक स्ट्रिंग इंजेक्षन करना चाहते हैं? निम्नलिखित स्निपेट की तरह कुछ के बारे में क्या?

Date now = new Date(); 
Date thirtyDaysAgo = new Date(now.getTime() - (30 * MS_IN_DAY)); 

Query q = em.createQuery("Select m from Message m " 
    + "where m.targetTime < :now and m.targetTime > :thirtyDays"); 
q.setParameter("now", now); 
q.setParameter("thirtyDays", thirtyDaysAgo); 

List<Message> results = (List<Message>) q.getResultList(); 
+4

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

+4

एफवाईआई, जेपीक्यूएल में, आप कास्ट से बचने के लिए एक टाइपेडQuery का उपयोग कर सकते हैं। –

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