2011-12-23 18 views
6

मैंने अतीत में कुछ जेपीए सामान बनाए हैं जो डीएओ के प्रति उदाहरण javax.persistence.EntityManager का उदाहरण इस्तेमाल करते हैं; इस तरह से अधिकांश उदाहरण सेटअप हैं।जेपीए EntityManager स्टेटिक या इंस्टेंस?

public class BaseDaoThatEveryDaoExtends { 
    @PersistenceContext 
    private EntityManager entityManager; 
} 

मैं सिर्फ कोड पर ठोकर खाई है कि का उपयोग करता है एक स्थिरjavax.peristence.EntityManger एक PersistenceContext एनोटेशन द्वारा इंजेक्शन, वास्तुकार मुझसे कहता है यह कोई समस्या नहीं होती है और वे भी JTA और एक साथ एक संकुल आवेदन में किसी भी समस्या थी कभी नहीं XA डेटा स्रोत:

public class BaseDaoThatEveryDaoExtends { 
    @PersistenceContext 
    private static EntityManager entityManager; 
} 

जहाँ तक मुझे इस बता सकते हैं के रूप में एक विरोधी पैटर्न के रूप में EntityManager कुछ राज्य सूचना रखती है और यह स्थिर बना देता है कि पूरे राज्य आवेदन चौड़ा है। इसके अलावा कक्षाओं को परीक्षण करने में बहुत मुश्किल होती है।

क्या ऐसा करने में कोई कमी है या क्या यह EntityManager का उपयोग करने का एक मानक तरीका है?

उत्तर

1

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

व्यक्तिगत रूप से, मैं इसे कभी भी स्थिर तरीके से परिभाषित नहीं करता। यह अनावश्यक लगता है, और सबसे खराब कुछ अप्रत्याशित साइड इफेक्ट्स हो सकता है।

public class BaseDaoThatEveryDaoExtends { 
    @PersistenceContext 
    private static EntityManager entityManager; 

    public static void doSomeStaticWork(){ 
     ... 
     entityManager.doSomething; //NPE possible! 
    } 
} 

मैं देख सकता EntityManager इंजेक्शन और इस मामले में एक एनपीई में जिसके परिणामस्वरूप नहीं किया जा रहा:

एक समस्या यह है मैं देख सकता हूँ की क्षमता अनजाने एक स्थिर विधि से entityManager तक पहुँचने के लिए है।

इसके अलावा EntityManager का उपयोग करके परीक्षण/मॉकिंग के आसपास कुछ समस्याएं हो सकती हैं।

+0

एक एनपीई भी अच्छी तरह से संभव है जब कोई मैन्युअल रूप से इंजेक्शन प्राप्त करने के बजाय डीएओ का उदाहरण बनाता है और उस पर इंस्टेंस विधियों का आह्वान करता है। तो यह वास्तव में एक तर्क नहीं है। – BalusC

+0

सिवाय इसके कि आपको BaseDaoThatEveryDaoExtends का निर्माण करने की आवश्यकता नहीं है, आप बस BaseDaoThatEveryDaoExtends.doSomeStaticwork() को कॉल करते हैं जिसके परिणामस्वरूप एनपीई हो सकता है। –

0

EntityManagerFactory को थ्रेड-सुरक्षित होने की गारंटी है, इसलिए मुझे लगता है कि यह "सही" तरीका है: थ्रेड-अन-सुरक्षित स्थानों में ईएमएफ का उपयोग करें और EntityManger को स्वयं थ्रेडिंग समस्याओं से सुरक्षित रखें।

4

मुझे लगता है कि प्रमुख जोखिम EntityManager में ही नहीं है, लेकिन अनुप्रयोग संदर्भ में जब यह उपयोग किया जाता है तो इकाई प्रबंधक से जुड़ा होता है।

मान लें कि आपके पास दो अलग-अलग क्लाइंट हैं जो आपके सर्वर के लिए अनुरोध करते हैं, दोनों आपके आवेदन के दो अलग-अलग तरीकों का आह्वान करते हैं, दोनों अलग-अलग धागे पर चल रहे हैं, लेकिन दोनों एक ही इकाई प्रबंधक का उपयोग करते हैं।

जहां तक ​​मुझे पता है कि इकाई प्रबंधक के पास एक ही संदर्भ संलग्न होगा, यह संदर्भ दोनों ग्राहकों द्वारा साझा किया जाएगा। प्रत्येक बार जब आप संदर्भ में एक उदाहरण लोड करते हैं, तो साझा इकाई प्रबंधक के माध्यम से धागे के लिए उपलब्ध होगा। क्या होगा यदि वे एक दूसरे के डेटा के साथ छेड़छाड़ करते हैं? क्या होगा यदि वे विभिन्न लेनदेन अलगाव विन्यास का उपयोग कर रहे हैं? आप संभवतः कैसे सुनिश्चित कर सकते हैं कि क्लाइंट 1 वर्तमान में क्लाइंट 2 द्वारा उपयोग किए जा रहे डेटा को परिवर्तित नहीं कर रहा है?

क्या होगा यदि कोई ग्राहक संदर्भ को अमान्य करता है, तो दूसरा क्या करेगा? इस तरह आप सहमति के साथ कैसे निपटते हैं?

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