2012-10-09 14 views
5

संभव डुप्लिकेट:
Hibernate: different object with the same identifier value was already associated with the sessionGrails त्रुटि "एक ही पहचानकर्ता मूल्य के साथ एक अलग वस्तु पहले से ही सत्र के साथ जुड़े थे"

मैं Grails में मेरी नियंत्रक में निम्न कोड है "a different object with the same identifier value was already associated with the session" त्रुटि संदेश के साथ विफल रहा है। मैं पहले से ही कुछ पन्नों का दौरा किया है जहां यह कहते हैं कि मैं बुला जो सेव इस त्रुटि के साथ समाप्त होता है Provided id of the wrong type for class com.easytha.QuizTag. Expected: class java.lang.Long, got class org.hibernate.action.DelayedPostInsertIdentifier

किसी ने सुझाव दिया है कि grails खोजा प्लगइन इस कारण हो सकता है और मैं खोजा = वास्तविक रूप मेरे डोमेन को निकाल देना चाहिए इससे पहले कि "merge" कॉल करना होगा कक्षा जो एक विकल्प नहीं है (पिछली पोस्ट देखें grails searcheable plugin search in inner hasMany class)

इंगित करने के लिए एक बात यह है कि q.save() को कॉल करने के समय त्रुटि को फेंक दिया नहीं जाता है बल्कि इसे पुनर्निर्देशित करने के दौरान फेंक दिया जाता है (कार्रवाई: " शो ", आईडी: आईडी) !!

कोई सुझाव? एक

def addTags(String tags,Long id){ 
     if(tags){ 
      String[] strTags = tags.split(","); 
      Quiz q = Quiz.get(id)   
      for(String t in strTags){ 
       Tag tagToAdd = Tag.findByTag(t) 

       if(!tagToAdd){ 
        tagToAdd = new Tag(tag:t) 
        tagToAdd.save() 
       } 

       println "---> "+tagToAdd +" Quiz"+q?.id 
       def qt = QuizTag.findByQuizAndTag(q,tagToAdd) 
       if(!qt){ 
        qt = new QuizTag(quiz:q,tag:tagToAdd); 
        q.addToTags(qt) 
       } 

      }   
      q.save()   
      redirect(action:"show",id:id) 
     } 
    } 

----------- संपादित ---------------

Final code that worked with searchable plugin 
     def addTags(String tags,Long id){ 
     if(tags){ 
      String[] strTags = tags.split(","); 
      Quiz q = Quiz.get(id)   
      for(String t in strTags){ 
       if (q.tags.any { QuizTag qt -> qt.tag.tag == t }) { continue; } 
        Tag tagToAdd = Tag.findOrSaveByTag(t); 
        QuizTag qt = new QuizTag(quiz:q,tag:tagToAdd) 
        q.addToTags(qt) 
       }   
      q.save(flush:true)  
      redirect(action:"show",id:id) 
     } 
    } 
+1

:

आप की तरह कुछ की कोशिश कर सकते "। वस्तु तुरंत कायम नहीं किया जाएगा जब तक कि फ्लश तर्क प्रयोग किया जाता है" यही कारण है कि त्रुटि तब होती है जब अनुरोध समाप्त होता है। –

+0

@TiagoFarias आप सही हैं। q.save (flush: true) को कॉल करने के बाद मुझे उस रेखा पर सही त्रुटि मिलती है, दूसरी बात यह है कि यहां ध्यान देने के बाद भी मेरा डेटा अभी भी सहेजा जा रहा है! यह त्रुटि केवल तभी होती है जब टैग पहले से मौजूद है "टैग.फिंडबीटाग (टी)" कुछ – Sap

उत्तर

0

हाइबरनेट प्रॉक्सी के साथ डिफ़ॉल्ट आलसी लोड संग्रह से Grails। तो शायद QuizTag प्रॉक्सी (या प्रॉक्सी और फुलाया वस्तुओं) डुप्लीकेट, बनाए जा रहे हैं जो आपकी समस्या का कारण है। बचाने() विधि का वर्णन से

Quiz q = Quiz.get(id)   
for(String t in strTags){ 
    // Check if the tag is already joined to this quiz and 
    // skip a dynamic finder load later 
    if (q.tags.any { QuizTag qt -> qt.tag.tag == t }) { continue; } 
    // Find or create-save the tag to join 
    Tag tagToAdd = Tag.findOrSaveByTag(t); 
    QuizTag qt = new QuizTag(quiz:q,tag:tagToAdd) 
    qt.save() 
    q.addToTags(qt) 
} 
+0

ठीक है, मेरा कोड ऊपर काम करता है लेकिन अब यह टैग और प्रश्नोत्तरी को अनुक्रमणित नहीं कर रहा है !! इसलिए कोई खोज परिणाम नहीं :) – Sap

+0

व्यवहार इतना यादृच्छिक प्रतीत होता है, यह सिर्फ एक पल पहले काम करना शुरू कर दिया था लेकिन अब q.save को कॉल करते समय वही त्रुटि (फ्लश: सत्य) – Sap

3

जब से तुम Quiz.get(id) करते हैं, आप ' कनेक्ट किए गए 'उदाहरण है, तो आप निश्चित रूप से करने की जरूरत नहीं' मर्ज '- कि केवल एक कट उदाहरण फिर से कनेक्ट करने के लिए है।

मुझे लगता है कि कारण यह है कि आप त्रुटि हो रही है कि लाइन है:

def qt = QuizTag.findByQuizAndTag(q, tagToAdd) 

सत्र में QuizTag उदाहरण खींचती है, लेकिन पहले से ही Tag tagToAdd = Tag.findByTag(t) सत्र के साथ उदाहरण संबंधित किया जाता है, और आप बताए जाते हैं एक और चर के लिए। अब आप दो सत्र से संबद्ध मामले हैं तो दोनों डेटाबेस में एक ही पंक्ति का प्रतिनिधित्व करने, qt और tagToAdd (वे एक ही आईडी है)। यह एक संदिग्ध स्थिति पैदा करता है, और इसकी अनुमति नहीं है, इसलिए त्रुटि।

ऐसा प्रतीत होता है कि आप वास्तव में qt instantiated जा करने के लिए (आप केवल कार्रवाई करने अगर यह मौजूद नहीं है) की जरूरत नहीं है कि। तो, मैं एक प्रश्न कर पता लगाने के लिए यदि वह मौजूद है (शायद एक 'select count') के बजाय वास्तव में वस्तु दृष्टान्त को पुन: प्राप्त सुझाव देना चाहेंगे। इस तरह, आपके पास ऑब्जेक्ट की केवल एक प्रति होगी।

+0

देता है आपके सुझाव के अनुसार "EDIT" में नया कोड काम नहीं करना चाहिए? – Sap

+0

मुझे खेद है, मैं आपके प्रश्न को समझ नहीं पा रहा हूं। "EDIT में नया कोड" क्या है? – GreyBeardedGeek

+0

:) मेरा मतलब मूल पोस्ट में संपादित क्षेत्र है। जहां मैंने टैग टैग ToAdd = Tag.findByTag (टी) ?: नया टैग (टैग: टी) और डीफ़ qt = QuizTag.findByQuizAndTag (q, tagToAdd) को वैरिएबल असाइनमेंट बदल दिया ?: नया क्विज़टैग (प्रश्नोत्तरी: क्यू, टैग: टैग टू एड); आपको नहीं लगता कि काम कर सकता था! – Sap

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

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