2010-03-08 11 views
6

हमारे पास कुछ जावाईई 5 स्टेटलेस ईजेबी बीन है जो इंजेक्शन एंटीटी मैनेजर को इसके सहायकों को पास करता है।क्या ईजेबी बीन के सहायक वर्गों में इंजेक्शन एंटाइटी मैनेजर पास करना ठीक है और इसका उपयोग करना ठीक है?

क्या यह सुरक्षित है? इसने अब तक अच्छी तरह से काम किया है, लेकिन मुझे कुछ ओरेकल दस्तावेज़ मिला जो बताता है कि EntityManager का कार्यान्वयन थ्रेड-सुरक्षित है। अब मुझे आश्चर्य है कि अब तक हमारे पास कोई समस्या नहीं है, केवल इसलिए कि हम जिस कार्यान्वयन का उपयोग कर रहे थे वह थ्रेड-सुरक्षित (हम ओरेकल का उपयोग करते थे)।

@Stateless 
class SomeBean { 
    @PersistenceContext 
    private EntityManager em; 

    private SomeHelper helper; 

    @PostConstruct 
    public void init(){ 
     helper = new SomeHelper(em); 
    } 

    @Override 
    public void business(){ 
     helper.doSomethingWithEm(); 
    } 

} 

वास्तव में यह समझ में आता है .. तो EntityManager धागे की असुरक्षित है, एक कंटेनर

inercept business() 
this.em = newEntityManager(); 
business(); 

जो अपनी सहायक वर्गों के लिए प्रचार नहीं करेंगे करने के लिए होगा।

यदि हां, तो इस तरह की स्थिति में सबसे अच्छा अभ्यास क्या है? EntityManager के बजाय EntityManagerFactory पास करना?

संपादित करें: This question बहुत ही दिलचस्प है, इसलिए यदि आप इस सवाल में रुचि रखते हैं, तो आप शायद इस एक भी बाहर की जाँच करना चाहते हैं:

संपादित करें: अधिक जानकारी। ejb3.0 spec

4.7.11 गैर रैत्रांत उदाहरण कंटेनर सुनिश्चित करना चाहिए कि केवल एक ही धागा किसी भी समय एक उदाहरण को क्रियान्वित किया जा सकता है। एक ग्राहक के अनुरोध एक उदाहरण के लिए आता है, जबकि उदाहरण एक और अनुरोध को क्रियान्वित किया जाता है, कंटेनर दूसरा ग्राहक [24] को javax.ejb.ConcurrentAccessException फेंक सकता है। EJB 2.1 ग्राहक दृश्य का उपयोग किया जाता है, तो कंटेनर java.rmi.RemoteException को दूसरा अनुरोध अगर ग्राहक एक दूरस्थ क्लाइंट, या javax.ejb.EJBException है फेंक सकता है अगर ग्राहक एक स्थानीय है ग्राहक। [25] ध्यान दें कि सत्र ऑब्जेक्ट का उद्देश्य केवल एक ही क्लाइंट का समर्थन करना है। इसलिए, एक अनुप्रयोग त्रुटि होगी यदि दो क्लाइंट ने उसी सत्र ऑब्जेक्ट का आह्वान करने का प्रयास किया। का एक निहितार्थ यह नियम है कि एक अनुप्रयोग सत्र बीन उदाहरण में लूपबैक कॉल नहीं कर सकता है।

और,

4.3.2 निर्भरता इंजेक्शन एक सत्र सेम निर्भरता इंजेक्शन कार्यविधि इसकी वातावरण में संसाधनों या अन्य वस्तुओं के लिए संदर्भ प्राप्त करने के लिए उपयोग कर सकते हैं (अध्याय 16, देखना "एंटरप्राइज़ बीन पर्यावरण")। एक सत्र सेम निर्भरता इंजेक्शन का इस्तेमाल करता है, तो कंटेनर injects सेम उदाहरण के बाद इन संदर्भ बनाई गई है, और किसी भी व्यवसाय से पहले तरीकों सेम उदाहरण पर लागू कर रहे हैं।यदि पर निर्भरता सत्रकॉन्टेक्स्ट घोषित की गई है, या बीन कक्षा वैकल्पिक सत्रबियन इंटरफ़ेस लागू करती है (अनुभाग 4.3.5 देखें), इस समय सत्र कॉन्टेक्स्ट को भी इंजेक्शन दिया गया है। यदि निर्भरता इंजेक्शन विफल रहता है, तो बीन उदाहरण छोड़ दिया गया है। ईजेबी 3.0 एपीआई के तहत, बीन क्लास सत्र कॉन्टेक्स्ट इंटरफ़ेस निर्भरता इंजेक्शन के माध्यम से सत्र सत्र इंटरफ़ेस को लागू किए बिना प्राप्त कर सकता है। इस मामले में, संसाधन एनोटेशन (या संसाधन-एनवी-रेफ तैनाती डिस्क्रिप्टर तत्व) सत्र कॉन्टेक्स्ट पर बीन की निर्भरता को इंगित करने के लिए उपयोग किया जाता है। अध्याय 16, "एंटरप्राइज़ बीन पर्यावरण" देखें।

+0

अब यह दिलचस्प है "ईजेबी 3.1 स्पेक का कहना है कि निर्भरता इंजेक्शन केवल निर्माण समय पर किया जाता है, ताकि MyRepository के सभी कॉलर्स EntityManager के एक ही उदाहरण का उपयोग करेंगे।" : http: //stackoverflow.com/questions/2015184/how-is-threadsafty-guranteed-with-persistencecontext –

+0

FYI, § 4.1.13 भी पढ़ें, या यह उत्तर http: // stackoverflow पढ़ें।com/प्रश्न/1954137/कैसे-है-कि-उदाहरण-पूलिंग-साथ-EJBs-कर सकते हैं-में सुधार प्रदर्शन/1954229 # 1954229। इसलिए प्रत्येक सहायक को एक समय में एक थ्रेड से पहुंचाया जाएगा। – ewernli

+0

यह वही पैटर्न है जिसे मैं कार्यान्वित करने के बारे में सोच रहा था। मुझे यह देखकर बहुत खुशी हुई कि यह संभव है। महान पद। धन्यवाद। – b3bop

उत्तर

2

मैंने एक समान पैटर्न का उपयोग किया, लेकिन सहायक @PostConstruct में बनाया गया था और इंजेक्शन इकाई प्रबंधक को पैरामीटर के रूप में निर्माता में पास किया गया था। प्रत्येक ईजेबी उदाहरण के अपने स्वयं के सहायक थे और थ्रेड-सुरक्षा की गारंटी थी।

मेरे पास एक संस्करण भी था जिसे इकाई प्रबंधक इंजेक्शन नहीं दिया गया था (क्योंकि ईजेबी इसे पूरी तरह से उपयोग नहीं कर रहा था), इसलिए सहायक को इसे InitialContext के साथ देखना होगा। इस मामले में, हठ संदर्भ अभी भी @PersistenceContext के साथ "आयातित" किया जाना चाहिए माता पिता EJB में:

@Stateless 
@PersistenceContext(name="OrderEM") 
public class MySessionBean implements MyInterface { 
    @Resource SessionContext ctx; 
    public void doSomething() { 
    EntityManager em = (EntityManager)ctx.lookup("OrderEM"); 
    ... 
    } 
} 

लेकिन यह वास्तव में इसकी सुई (भले ही EJB इसका इस्तेमाल नहीं करता है) यह देखने के लिए अप करने के लिए की तुलना में आसान है , खासकर टेस्टेबिलिटी के लिए।

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

उम्मीद है कि यह मदद करता है।

संपादित

§ 3.3 अनुभाग और § कल्पना में 5.6 थोड़ा विषय को कवर।

+0

धन्यवाद, मुझे यह सुनकर खुशी हो रही है कि हमें हमारे उत्पादन कोड के माध्यम से खोदना नहीं है! –

2

मैं सहायक तरीकों का उपयोग कर दिया गया है और वहाँ EntityManager पारित कर दिया है, और यह पूरी तरह से ठीक है।

तो मैं या तो तरीकों को इसे पारित जब भी जरूरत की सलाह देते हैं, या सहायक एक सेम ही करते हैं, इसकी सुई (@EJB प्रयोग करके) और EntityManager वहाँ के रूप में अच्छी इंजेक्षन।

+0

सहायक तरीके वास्तव में सरल और अच्छी लगती है। धन्यवाद! –

0

अच्छा, व्यक्तिगत रूप से, मैं अपने रचनाकारों या विधियों में अपने सभी पीओजेओ को एंटिटी मैनेजर पास नहीं करना चाहता हूं। खासकर गैर-तुच्छ कार्यक्रमों के लिए जहां पीओजेओ की संख्या बड़ी है।

मैं पीओजेओ/हेल्पर क्लास बनाने की कोशिश करता हूं जो EntityManager द्वारा लौटाई गई संस्थाओं से निपटने की कोशिश करता है, बजाय इकाई प्रबंधक का उपयोग करने के बजाय।

यदि संभव नहीं है, तो मुझे लगता है कि मैं एक नया ईजेबी बीन बनाउंगा।

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