2017-05-05 7 views
10

का उपयोग करते समय OptimisticLockException मेरे पास एक बाकी एप्लिकेशन है जहां संसाधनों में से एक को अपडेट किया जा सकता है। (आशावादी लॉकिंग के लिए इस्तेमाल किया) प्राप्त करता है आईडी और नई वस्तु स्टोर जो PUT अनुरोध इकाई deserializing द्वारा बनवाया गया था, संस्करण सेट:जेपीए मर्ज()

  1. updateWithRelatedEntities (स्ट्रिंग, स्टोर): नीचे दो तरीकों इस कार्य को प्राप्त करने के लिए जिम्मेदार हैं नए ऑब्जेक्ट पर और लेनदेन में कॉल अपडेट करें।

    public Store updateWithRelatedEntities(String id, Store newStore) { 
        Store existingStore = this.get(id); 
    
        newStore.setVersion(existingStore.getVersion()); 
    
        em.getTransaction().begin(); 
        newStore = super.update(id, newStore); 
        em.getTransaction().commit(); 
    
        return newStore; 
    } 
    
  2. अद्यतन (स्ट्रिंग, टी): एक अद्यतन बनाने के लिए एक सामान्य विधि। जांचता है कि आईडी मेल खाते हैं और मर्ज ऑपरेशन करते हैं। T obj = em.find(type, id); डेटाबेस में दुकान वस्तु का एक अद्यतन जिसका अर्थ है कि हम OptimisticLockException जब merge ट्रिगर (क्योंकि संस्करणों अब अलग हैं) मिल चलाता है:

    public T update(String id, T newObj) { 
        if (newObj == null) { 
        throw new EmptyPayloadException(type.getSimpleName()); 
        } 
    
    
        Type superclass = getClass().getGenericSuperclass(); 
    
        if (superclass instanceof Class) { 
         superclass = ((Class) superclass).getGenericSuperclass(); 
        } 
    
        Class<T> type = (Class<T>) (((ParameterizedType) superclass).getActualTypeArguments()[0]); 
    
        T obj = em.find(type, id); 
    
        if (!newObj.getId().equals(obj.getId())) { 
         throw new IdMismatchException(id, newObj.getId()); 
        } 
    
        return em.merge(newObj); 
    } 
    

समस्या यह है कि इस कॉल है।

ऐसा क्यों हो रहा है? इसे हासिल करने का सही तरीका क्या होगा? जो होता है, मुझे लगता है, आशावादी लॉक समस्या का समाधान -

मैं एक तरह से existingStore को newStore से गुण कॉपी और मर्ज के लिए existingStore उपयोग करने के लिए नहीं करना चाहती।

यह कोड किसी एप्लिकेशन सर्वर पर नहीं चल रहा है और मैं जेटीए का उपयोग नहीं कर रहा हूं।

संपादित: अगर मैं अद्यतन कॉल करने से पहले existingStore अलग, T obj = em.find(type, id); इसलिए इस समस्या का हल दुकान वस्तु के अपडेट ट्रिगर नहीं है। प्रश्न अभी भी बनी हुई है - जब इकाई अलग नहीं होती है तो यह क्यों ट्रिगर करता है?

+0

क्या आप आशावादी लॉकिंग की अवधारणा को समझते हैं? – Kayaman

+0

हां, मैं अवधारणा को समझता हूं और मुझे यह त्रुटि क्यों मिल रही है। जो मुझे समझ में नहीं आता है, यही कारण है कि जेपीए (आईडी) को कॉल करते समय संस्करण अपडेट करता है जो मर्ज कॉल करते समय OptimistiLockException में जाता है। –

+0

'get (id)' जैसा दिखता है? – Kayaman

उत्तर

1

मैं आपकी इकाई को आपके द्वारा जोड़े गए कोड से नहीं देख सकता लेकिन मुझे विश्वास है कि आप आशावादी लॉकिंग के साथ कुछ महत्वपूर्ण बिंदु खो रहे हैं ->@Version संस्करण फ़ील्ड पर एनोटेशन। यदि आपके पास यह इकाई आपकी इकाई पर है तो कंटेनर समस्याओं के बिना विलय प्रक्रिया करने में सक्षम होना चाहिए। कृपया Optimistic Locking पर भी एक अच्छा लेख देखें don't break optimistic locking

+0

मैं '@ संस्करण' फ़ील्ड का उपयोग कर रहा हूं, समस्या यह है कि मैं एक नई वस्तु (deserializing द्वारा निर्मित) के साथ अद्यतन कर रहा हूं, इसलिए मुझे मैन्युअल रूप से' @ संस्करण' फ़ील्ड सेट करना होगा। –

+0

आप ऑब्जेक्ट को केवल deserialize क्यों नहीं करते हैं और इसे आईडी लेते हैं, एक 'em.find' करें और फिर आप उचित इकाई को अपडेट कर सकते हैं। आप वर्तमान में क्या कर रहे हैं थोड़े हैकी .. – galovics

+0

यह एक समाधान होगा, लेकिन मुझे यह पसंद नहीं है, क्योंकि मुझे पता है कि मैं कौन से फ़ील्ड कॉपी नहीं करना चाहता हूं और दूसरी तरफ नहीं। इसलिए यदि मैं भविष्य में इकाई में एक फ़ील्ड जोड़ता हूं, तो मुझे याद रखना होगा कि मुझे उस फ़ील्ड को कोडबेस के दूसरे हिस्से में भी जोड़ना होगा। –