दिलचस्प पोस्ट
कैसे जाँचें कि कोई गर्तिका जुड़ा / सी # में डिस्कनेक्ट हो गई है? सेलेनियम के साथ Google क्रोम डेवलपर टूल पर नेटवर्क पैनल का उपयोग कैसे करें? CakePHP में base_url जीसीसी विकल्प को समझने की कोशिश करना- फोमट-फ्रेम-पॉइंटर कोणीय के साथ jQuery का उपयोग कैसे करें? मैक्रोज तर्क पर Foreach मैक्रो WPF INotifyPropertyChanged कैसे काम करता है? Google साइन-इन IO 9 पर क्रैश करता है, जिसे कैन ओपनURL कहते हैं जावा स्ट्रिंग्स: "स्ट्रिंग s = नया स्ट्रिंग (" मूर्ख ");" मैं जावा में कैसे लावा एम्बेड कर सकता हूँ? वेब। Xml में श्वेतसूची सुरक्षा बाधा Android में खारिज या रद्द किए जाने वाले संवाद में क्या अंतर है? ASP.NET MVC 5 मोनो में रेजर यूआर हेल्पर्स का उपयोग करते समय विधि 'RouteCollection.get_AppendTrailingSlash' नहीं मिला एचटीएमएल टैग्स <div> और <span> के बीच अंतर क्या है? लाइन द्वारा एक फ़ाइल लाइन में (अपडेट) टेक्स्ट को कैसे बदलें

जब EntityManager.find () बनाम EntityManager.getReference () का उपयोग करें

मैं एक ऐसी स्थिति में आया हूं (जो मुझे लगता है कि यह अजीब है लेकिन संभवतः काफी सामान्य है) जहां मैं EntityManager.getReference (LObj.getClass (), LObj.getId ()) का उपयोग डेटाबेस इकाई प्राप्त करने के लिए करता हूं और फिर लौटा हुआ ऑब्जेक्ट को दूसरे टेबल में बने रहें

तो मूल रूप से प्रवाह इस तरह था:

 वर्ग TFacade {

   createT (एफओबीजे, एओबीजे) {
     टी टूबज = नया टी ();
     TObj.setF (FObj);
     TObj.setA (AObj);
     ...
     EntityManager.persist (TObj);
     ...
     एल LObj = A.getL ();
     FObj.setL (LObj);
     FFacade.editF (FObj);
   }
 }

 @ TransactionAttributeType.REQUIRES_NEW
 कक्षा FFacade {

   editF (FObj) {
     एल LObj = FObj.getL ();
     LObj = EntityManager.getReference (LObj.getClass (), LObj.getId ());
     ...
     EntityManager.merge (FObj);
     ...
     एफएचएचएफएकेड.क्रेडिट (एफओबीजे, लोब);
   }
 }

 @ TransactionAttributeType.REQUIRED
 क्लास एफएचएचएफ़ैकेड {

   बनाने एफएलएच (एफओबीजे, लोब) {
     FLH FLHObj = नया FLH ();
     FLHObj.setF (FObj);
     FLHObj.setL (LObj);
     ....
     EntityManager.persist (FLHObj);
     ...
   }
 }

मुझे निम्नलिखित अपवाद "java.lang.IllegalArgumentException: अज्ञात इकाई: com.my.preistence.L $$ EnhancerByCGLIB $$ 3e7987d0" मिल रहा था

थोड़ी देर के लिए इस पर गौर करने के बाद, मुझे अंत में पता चला कि यह इसलिए था क्योंकि मैं EntityManager.getReference () विधि का उपयोग कर रहा था, जिस पर मुझे ऊपर अपवाद मिल रहा था, विधि के रूप में एक प्रॉक्सी लौट रहा था।

इससे मुझे आश्चर्य होता है, जब EntityManager.find () विधि के बजाय EntityManager.getReference () विधि का उपयोग करने की सलाह दी जाती है ?

EntityManager.getReference () एक EntityNotFoundException फेंकता है अगर वह खोज नहीं किया जा रहा है जो इकाई खोज के लिए है जो अपने आप में बहुत सुविधाजनक है EntityManager.find () विधि केवल रिक्त रिटर्न अगर यह इकाई नहीं मिल सकता है।

लेन-देन की सीमाओं के संबंध में, मुझे लगता है जैसे आप नए तत्वों को एक नए लेनदेन के पास करने से पहले () विधि का उपयोग करने की आवश्यकता होगी। यदि आप getReference () पद्धति का उपयोग करते हैं, तो शायद आप ऊपर की अपवाद के साथ मेरी स्थिति के समान ही समाप्त हो जाएंगे।

Solutions Collecting From Web of "जब EntityManager.find () बनाम EntityManager.getReference () का उपयोग करें"

मैं आमतौर पर getReference विधि का उपयोग करता हूं जब मुझे डाटाबेस स्थिति तक पहुंचने की ज़रूरत नहीं होती है (मेरा मतलब है गेटर विधि)। बस राज्य को बदलने के लिए (मैं सेटर विधि मतलब है) जैसा कि आपको पता होना चाहिए, getReference एक प्रॉक्सी ऑब्जेक्ट देता है जो स्वचालित गंदा जांच नामक एक शक्तिशाली सुविधा का उपयोग करता है निम्नलिखित मान लीजिए

public class Person { private String name; private Integer age; } public class PersonServiceImpl implements PersonService { public void changeAge(Integer personId, Integer newAge) { Person person = em.getReference(Person.class, personId); // person is a proxy person.setAge(newAge); } } 

अगर मैं विधि ढूंढता हूं, तो जेपीए प्रदाता, पर्दे के पीछे, कॉल करेंगे

 SELECT NAME, AGE FROM PERSON WHERE PERSON_ID = ? UPDATE PERSON SET AGE = ? WHERE PERSON_ID = ? 

अगर मैं getrereference विधि कॉल, जेपीए प्रदाता, पर्दे के पीछे, कॉल करेंगे

 UPDATE PERSON SET AGE = ? WHERE PERSON_ID = ? 

और तुम्हें पता है क्यों ???

जब आप getreference को कॉल करते हैं, तो आपको एक प्रॉक्सी ऑब्जेक्ट मिलेगा। इस तरह से कुछ (जेपीए प्रदाता इस प्रॉक्सी को कार्यान्वित करने का ख्याल रखता है)

 public class PersonProxy { // JPA provider sets up this field when you call getReference private Integer personId; private String query = "UPDATE PERSON SET "; private boolean stateChanged = false; public void setAge(Integer newAge) { stateChanged = true; query += query + "AGE = " + newAge; } } 

लेनदेन प्रतिबद्ध होने से पहले, जेपीए प्रदाता को अपडेट करने के लिए या नोड व्यक्ति इकाई को बदलकर झंडी दिखाई देगी। यदि अद्यतन कथन के बाद कोई पंक्ति अपडेट नहीं की जाती है, तो जेपीए प्रदाता JPY विनिर्देश के अनुसार EntityNotFoundException फेंक देगा।

सादर,

क्योंकि एक संदर्भ 'प्रबंधित' है, लेकिन हाइड्रेटेड नहीं है, यह आपको आईडी में किसी संस्था को निकालने की अनुमति भी दे सकता है, बिना इसे स्मृति में पहले लोड करने की आवश्यकता है।

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

 MyLargeObject myObject = em.getReference(MyLargeObject.class, objectId); em.remove(myObject);