2013-02-20 116 views
8

मैं गूल App इंजन का उपयोग कर रहा मेरी REST API का निर्माण करने के लिए, मैं पहले से ही के रूप में PersistenceCapable मेरी कक्षा में चिह्नित किया है और मैं भी मेरी @PrimaryKey परिभाषित है और यह भी चिह्नित कर ली के रूप में @Persistent (valueStrategy = IdGeneratorStrategy.IDENTITY), मैं भी पहले ही एंडपॉइंट उत्पन्न कर चुका हूं। लेकिन जब मैं टर्मिनल विंडो में टाइप करता हूं तो एक नई इकाई या रजिस्ट्री डालने के लिए एक curl कमांड काम नहीं करता है।उत्पन्न स्वत: ईद IdGeneratorStrategy

@PersistenceCapable(identityType = IdentityType.APPLICATION) 
class Student{ 
    @PrimaryKey 
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
    private Long  id; 
    private String studentName; 
    .... 
    .... 
    .... 
} 

इस कर्ल कमान और अपने स्थानीय सर्वर से प्रतिक्रिया है: इस कोड है। जब मैं एक नई इकाई

curl -H 'Content-Type: application/json' -d'{"studentName": "myname"}' htto://localhost:8889/_ah/api/utp/v1/student 

सम्मिलित करने के लिए कोशिश करते हैं और इस स्थानीय सर्वर से प्रतिक्रिया है।

"error" : { 
"message" : "javax.jdo.JDOFatalInternalException: El valor de llave dado para construir una identidad de SingleFieldIdentity de tipo \"class javax.jdo.identity.LongIdentity\" para la clase \"class com.alex.wserver.Student\" es nulo.\nNestedThrowables:\norg.datanucleus.exceptions.NucleusException: El valor de llave dado para construir una identidad de SingleFieldIdentity de tipo \"class javax.jdo.identity.LongIdentity\" para la clase \"class com.alex.wserver.Student\" es nulo." 

मैं सोच रहा हूं कि आईडी स्वचालित रूप से डाली गई थी। लेकिन यह यहाँ नहीं हो रहा है। के विपरीत एक आईडी एक साथ


  1. मेरी कक्षा गलत हैं डालने?
  2. मेरे पोस्ट/जेसन अनुरोध ठीक है?

अग्रिम धन्यवाद।

+0

और लॉग क्या कहता है? (मैं ऊपर पोस्ट किए गए उन हाइरोग्लिफिक्स को भी नहीं पढ़ सकता; मुझे वहां कोई जावा दृढ़ता कोड नहीं दिखता है, जैसे pm.makePersistent)। – DataNucleus

+0

आप सीधे कोड स्निपेट चिपका सकते थे। चित्र थोड़े छोटे और समझने में मुश्किल हैं। –

+0

मैंने कोड को स्नैप करके पहले ही छवियों को बदल दिया है ... खराब छवियों के लिए खेद है ... – AlexSanchez

उत्तर

8

मुझे लगता है कि मुझे समाधान मिला है। ऐसा लगता है कि Google App Engine (GAE) ढांचे द्वारा उत्पन्न हर एंडपॉइंट में एक साधारण विधि है जो हर बार जांचता है कि कोई व्यक्ति डालने या अपडेट करने और लगातार उदाहरण देने की कोशिश कर रहा है, इसलिए तथ्य यह था कि मैंने हर बार एक नया डालने की कोशिश की थी डी उदाहरण के लिए नई id का उल्लेख के बिना कर्ल/json का उपयोग कर छात्र यह इस तरह का त्रुटि संदेश दिखाई नहीं:

"error": { 
     "message": javax.jdo.JDOFatalInternalException: The key value passed to construct a 
     SingleFieldIdentity type \ class javax.jdo.identity.LongIdentity \ for class \ class com.alex.wserver.Student \ is null. \ nNestedThrowables: \ norg.datanucleus.exceptions.NucleusException: the key value passed to construct a SingleFieldIdentity type \ class javax.jdo.identity.LongIdentity \ for class \ class com.alex . wserver.Student \ is null. 

तो मैं जाँच करके संपादन मेरी endpoint वर्ग समस्या को हल कर दिया है, तो नई वस्तु (कर्ल कमांड और लिपटे जेसन प्रारूप द्वारा भेजा गया) इस कोड के साथ पहले ऑब्जेक्ट को संग्रहीत किया गया है या नहीं, यह जांचने से पहले शून्य आईडी मान नहीं है:

 if(student.getKey() != null){ 
      if (containsStudent(student)) { 
       throw new EntityExistsException("Object already exists"); 
      } 
     } 
     mgr.makePersistent(student); 

जहां तक ​​मैंने कोई दस्तावेज नहीं देखा है जो मेरे लिए उस पहलू को स्पष्ट कर सकता है। साथ ही, मैं यह भी पता लगाने से पहले कि क्या हो रहा है, यह जानने से पहले मैंने GAE पर दस्तावेज़ पढ़ने में बहुत समय व्यतीत किया है।


सभी है कि मुझे लगता है कि हो सकता है सिर्फ शायद GAE प्रलेखन तारीख तक नहीं है या शायद मैं पर्याप्त खोज, इसलिए यदि किसी के बारे में पता havent बनाया है। कृपया मुझे यह बताएं और सामान्य ज्ञान बढ़ें। धन्यवाद @ डेटान्यूक्लियस।

नोट: "। यह कांटा है कि मैं सही जवाब के रूप में taked नहीं किया जाना चाहिए करने के बाद, यह अपने अनुप्रयोग के अप्रत्याशित व्यवहार के लिए ले जा सकता है"

+1

+1 आप मेरा दिन बचा लिया! इसे जीपीई की एक बग माना जा सकता है जो Google क्लाउड एंडपॉइंट्स के लिए अवांछनीय कोड उत्पन्न करता है। –

+2

हैलो @ टोयहंटर, मैंने कुछ शोध किया है और मुझे एक बेहतर समाधान मिला है। अब मैं एक स्थिर इटरेटर ऑब्जेक्ट का उपयोग कर रहा हूं जिसमें कुंजी की एक श्रृंखला शामिल है। इसलिए हर बार जब मैं एक नई इकाई पोस्ट करता हूं तो मुझे नई वस्तु के लिए नई कुंजी मिलती है। मैंने एंडपॉइंट क्लास के अंदर एक निजी स्थैतिक विधि लिखी जो इटरेटर को प्रारंभ करता है, इसलिए जब मैं एक नई वस्तु पोस्ट करता हूं तो इटेटरेटर को एक नई कुंजी मिलती है और मैं इसे केवल नए ऑब्जेक्ट को सौंपता हूं और इसे जारी रखता हूं। कुछ [संदर्भ] (https://developers.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/KeyRange) – AlexSanchez

+1

+1 आपका दृष्टिकोण परिप्रेक्ष्य से निश्चित रूप से सहायक है कि लोग डेटा माइग्रेशन के माध्यम से आईडी को संरक्षित करना चाहते हैं। बस सोच रहा है कि इन सभी मुद्दों को पहले से ही ऐप इंजन द्वारा क्यों ख्याल रखा जाता है। –

0

जैसा कि एलेक्सशेन्ज़ द्वारा दिए गए जवाब में टिप्पणी की गई है, जेनरेटेड एंडपॉइंट कोड अपेक्षा करता है कि प्राथमिक कुंजी पहले से ही नई पहचान डालने पर सेट हो।

जबकि कुछ इसे एक बग के रूप में देख सकते हैं, अन्य लोग एक सुविधा के रूप में देख सकते हैं, क्योंकि क्लाइंट को किसी भी तरह की कुंजी उत्पन्न करने की आवश्यकता होती है (उदाहरण के लिए कुंजी प्रकार स्ट्रिंग होने पर यादृच्छिक यूयूआईडी बनाकर)। इस तरह, क्लाइंट ऑफलाइन होने पर भी इकाइयों का पूरा ग्राफ बना सकता है और उन्हें ऑनलाइन सर्वर पर अपलोड कर सकता है।

(मुझे लगता है कि स्पाइन ढांचा इस विचार के लिए एक उदाहरण है:। http://spinejs.com/)

1

समस्या निहित में endpoint कि स्वचालित रूप से उत्पन्न किया गया था की विधि में शामिल है। अपवाद को फेंक दिया जा रहा है javax.jdo.JDOFatalInternalException जब आईडी शून्य है और विधि अपवाद javax.jdo.JDOObjectNotFoundException पकड़ता है।

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

उम्मीद है कि यह मदद करता है!

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

  • कोई संबंधित समस्या नहीं^_^