2011-08-31 13 views
7

मैं अपने ओआरएम के रूप में डॉक्टर 2 का उपयोग कर रहा हूं, और चीजें अच्छी तरह से चल रही हैं, लेकिन मैं EntityManager#persist() विधि के बारे में सोच रहा हूं। "Persisting entities" प्रलेखन वस्तु X के लिए persist() के लिए एक कॉल के बारे में निम्नलिखित कहते हैं:जब कॉल करना है

हैं एक्स एक पहले से मौजूद कामयाब इकाई है, यह जारी रहती है आपरेशन के द्वारा नजरअंदाज कर दिया है।

इससे मुझे विश्वास होता है कि persist() केवल ऑब्जेक्ट नया होने पर ही कॉल किया जाना चाहिए और अभी तक डेटाबेस में सहेजा नहीं गया है। हालांकि, "Deferred Explicit" change tracking policy के लिए दस्तावेज़ का कहना है:

... सिद्धांत 2 केवल संस्थाओं से, जिन्हें स्पष्ट रूप से परिवर्तन का पता लगाने के लिए चिह्नित किया गया जारी रहती है (इकाई) EntityManager के लिए एक कॉल # के माध्यम से समझता है ...

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

उत्तर

8

Deferred Explicit policy (यह डिफ़ॉल्ट नीति नहीं है) के साथ, आपको सिद्धांतों के लिए प्रत्येक संशोधित इकाई पर लगातार बने रहने के लिए स्पष्ट रूप से कॉल() को कॉल करना होगा। (सिवाय के लिए झरना-जारी रहती संघों।)

सिद्धांत अभी भी मूल मूल्य के साथ प्रत्येक संपत्ति के नए मूल्य की तुलना करने के जो संपत्ति को अद्यतन करने के लिए ज़रूरी है, तो यह एक प्रदर्शन हिट अगर आप persist() बहुत ज्यादा संस्थाओं हो सकता है।

default change tracking policy के साथ आपको केवल उन संस्थाओं पर लगातार कॉल करने की आवश्यकता है जिन्हें अभी तक सिद्धांत द्वारा प्रबंधित नहीं किया गया है (संस्थाएं जिन्हें आपने new के साथ बनाया था)। इस नीति के साथ, जब आप फ्लश() सिद्धांत को कॉल करते हैं तो स्वचालित रूप से पता लगाता है कि कौन सी संस्थाएं अपडेट की गई हैं और उन्हें जारी रखने की आवश्यकता है।

+0

ध्यान दें कि डिफर्ड इम्प्लीट चेंज ट्रैकिंग (डिफ़ॉल्ट) का उपयोग करते समय, सिद्धांत यूनिटऑफवर्क में मौजूद प्रत्येक इकाई के लिए प्रत्येक संपत्ति के लिए नए मूल्य (अब तक डिफर्ड स्पष्टीकरण के समान) के साथ मूल मूल्य की तुलना करेगा, न केवल जिन्हें आप 'persist()' कहते हैं। –

+3

इस समस्या से उत्तेजित होने तक समस्या का आधा जीवन समाप्त हुआ कि डिफ़ॉल्ट नीति स्पष्ट नीति है। –

6

दस्तावेज़ीकरण कुछ हद तक भ्रामक है। निहित ट्रैकिंग मोड में, सभी इकाइयों में एक राज्य होता है (प्रबंधित, हटाया जाता है, अलग आदि); find() द्वारा प्राप्त इकाइयों और इसी तरह के तरीकों (मूल रूप से सब कुछ जो new के साथ नहीं बनाया गया है) पहले ही प्रबंधित स्थिति में हैं। flush() पर, सभी प्रबंधित (और हटाए गए) entites परिवर्तन के लिए चेक किए जाते हैं और यदि आवश्यक हो, तो डीबी में अपडेट किया गया।

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

आप Doctrine\ORM\UnitOfWork कक्षा में अपने लिए विवरण देख सकते हैं; isChangeTrackingDeferredImplicit/isChangeTrackingDeferredExplicit के लिए खोजें (वे केवल वे स्थान हैं जहां व्यवहार दो नीतियों के तहत भिन्न होता है)।

+0

मेरे पास एक पृथक इकाई (चैनल) आने वाला फॉर्म कैश्ड परिणाम सेट है जिसे मुझे डेटा तालिका को प्रभावित करने के लिए डेटा जोड़ने की आवश्यकता है। अलग चैनल विलय किए बिना चैनल के डेटा को जारी रखने का कोई तरीका है? – andig

+0

@andig, यकीन नहीं है। मैं इसे लेता हूं [इस सवाल] के बारे में आप बात कर रहे हैं (http://stackoverflow.com/questions/18102728/doctrine-persस्टिंग-detached-entities) - आपको वास्तव में चैनल को तब तक जारी रखने की आवश्यकता क्यों है जब आप वास्तव में जोड़ना चाहते हैं एक नई डेटा इकाई? – Tgr

+0

उत्कृष्ट सवाल। मैं विरासत कोड के साथ काम कर रहा हूं और अभी भी सिद्धांत के लिए नया हूं। जांच करेगा कि कैसे/अगर मैं सीधे 'डेटा' के ArrayCollection को जारी रख सकता हूं। अगर काम कर रहा हूं तो मैं एक क्रॉस-उत्तर की सराहना करता हूं ताकि मैं वोट दे सकूं। – andig

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