2014-05-06 3 views
6

मेरे पास एक वेब एप्लिकेशन है जिसमें कुछ अजीब व्यवहार है जहां मैं वास्तव में अपनी उंगली नहीं डाल सकता। मेरी समस्या का मूल यह है कि मेरे बाकी अंतराल द्वारा दिए गए मूल्यों में एक असंगत व्यवहार है। जब मैं अपना आवेदन शुरू करता हूं, तो प्रत्येक बार जब मैं इस एंडपॉइंट को कॉल करता हूं तो मेरी क्वेरी वही मान देती है। जब मैं एक इकाई को अद्यतन करता हूं, तो मेरा इकाई प्रबंधक अजीब व्यवहार करना शुरू कर देता है। अब मेरी क्वेरी अलग-अलग परिणाम लौटाना शुरू कर देती है। एक बार यह डेटाबेस में मौजूद मानों के बजाय पुराने मान देता है या मेरी परिणाम सूची में ऑब्जेक्ट्स (मिश्रित) के बजाय प्रॉक्सी होती है। enter image description herejpa2 guice के साथ इकाई प्रबंधक का पुन: उपयोग करता है

मैं पुष्टि की है कि मेरे @transaction तरीकों को सही ढंग से रखा जाता है और मेरे डिबग स्टैक में मैं देख रहा हूँ लेनदेन इंटरसेप्टर और इकाई प्रबंधक अनुरोध के अनुसार बैकएंड (ताकि कोई guice हठ फिल्टर)

मेरे लिए बनाई गई है भावना इंगित करती है कि समस्या सत्र संदर्भ में निहित है। मुझे लगता है (लेकिन मैं वास्तव में इसे समझ नहीं सकता) कि यह कई अनुरोधों पर मेरे दृढ़ता संदर्भ का पुन: उपयोग करता है।

मैंने यह सब काम करने के लिए कुछ ढांचे को एक साथ रखा है। मैं जैक्स-आरएस कार्यान्वयन के रूप में resteasy का उपयोग करें। guice (4.0beta4) सीडीआई कार्यान्वयन के रूप में और जेपीए कार्यान्वयन के रूप में हाइबरनेट। क्योंकि जब हम इकाई प्रबंधक को इंजेक्ट करते हैं तो हमें प्रदाता का उपयोग करने की आवश्यकता होती है (चूंकि इकाई प्रबंधक प्रत्येक लेनदेन को बनाया जाता है), मैंने इसे EntityManagerProxy में लपेट लिया है। यह वर्ग EntityManager इंटरफ़ेस लागू करता है और प्रदाता.get()। विधि() में सभी विधियों को प्रतिनिधि करता है।

public class EntityManagerProxy implements EntityManager { 
    private final Provider<EntityManager> entityManagerProvider; 

    @Inject 
    public EntityManagerProxy(final Provider<EntityManager> entityManagerProvider) { 
     this.entityManagerProvider = entityManagerProvider; 
    } 

    private EntityManager getEntityManager() { 
     return entityManagerProvider.get(); 
    } 

    @Override 
    public void persist(final Object entity) { 
     getEntityManager().persist(entity); 
    } 
} 

मेरे guice मॉड्यूल इस

public class OptiWEEEModule extends ServletModule implements Module { 
    @Override 
    protected void configureServlets() { 

     super.configureServlets(); 
     bind(EntityManagerProxy.class); 
     // JPA 
     install(new JpaPersistModule("myPU")); 
    } 
} 

मैं जानता हूँ कि यह एक अस्पष्ट मुद्दा है की तरह लग रहा है, लेकिन किसी को सही दिशा में मेरी मदद कर सकता है? यह वास्तव में एक मुद्दा नहीं है जिसके लिए मैं एक त्रुटि संदेश प्रदान कर सकता हूं।

संपादित करें: अब मैं समस्या को इंगित करता हूं। एक प्रोफाइलर के साथ मैंने देखा कि इकाई कॉन्टेक्स्ट को गुइस द्वारा पुन: उपयोग किया जाता है। इसका अर्थ यह है कि यह हर बार क्वेरी निष्पादित नहीं करता है, लेकिन मौजूदा इकाई प्रबंधक का उपयोग करता है, जिसे प्रत्येक बार @transactional एनोटेशन पारित किया जाना चाहिए।

+0

मैं बस guice 4beta4 से guice 3 तक डाउनग्रेड किया गया और एक ही त्रुटि होती है। – jelle

+0

'ट्रांजेक्शनल' का विचार है कि आपको एक नया लेनदेन मिलता है, न कि एक नया EntityManager। उत्तरार्द्ध उन लोगों में से कुछ को भी संभाल सकता है। आप अपने प्रॉक्सी का "अपडेट" हिस्सा नहीं दिखाते हैं और न ही वेब सर्विसेज, इसलिए यह कहना मुश्किल है कि वास्तव में आपकी समस्या का कारण क्या है। – mabi

+0

मैं वास्तव में समस्या को कम कर दिया। अद्यतन भाग मेरे आवेदन को तोड़ नहीं है, लेकिन इकाई थ्रेड प्रत्येक थ्रेड पर पुन: उपयोग किया जाता है। मुझे लगता है कि मैं एक सिंगलटन बना रहा हूं जो मेरा इकाई प्रबंधक रखता है। क्या मेरी entitymanagerproxy इस कारण हो सकता है? यह वह रणनीति है जिसका मैं अनुसरण कर रहा हूं https://code.google.com/p/google-guice/wiki/JPA#Session-per-transaction_strategy – jelle

उत्तर

1

मुझे मेलिंग सूचियों से यह आयनसर मिला।

गुइस पेस्टिस्ट में ऐसी सुविधा है जो कुछ समस्याओं का कारण असामान्य है। मुझे लगता है कि आप इसे मार रहे हैं

जब आप कार्य guice की इकाई के बाहर किसी इकाई प्रबंधक से अनुरोध करते हैं तो लगातार आपके लिए काम की इकाई शुरू हो जाएगी। दुर्भाग्यवश यूनिटऑफवर्क पर isActive() पैकेज निजी है। और यदि कार्य की इकाई सक्रिय है तो आप का परीक्षण नहीं कर सकते।

काम की एक इकाई को स्पष्ट रूप से शुरू करने और समाप्त करने के दो तरीके हैं। आप यूनिटऑफवर्क का उपयोग कर सकते हैं और विधियां प्रारंभ() और अंत()। इसके अलावा @ ट्रांसेक्शनल एनोटेशन काम की एक इकाई शुरू करता है। @ ट्रांसेक्शनल काम की इकाई को भी समाप्त कर देगा अगर केवल इसे शुरू किया गया हो।

@ ट्रांस्सेक्शन विधि के भीतर केवल एक इकाई प्रबंधक प्राप्त करना सर्वोत्तम अभ्यास है।

मैं केवल यह निष्कर्ष निकाल सकता हूं कि @ ट्रान्सएक्शन एनोटेशन वसंत में एक के समान परिपक्वता स्तर का नहीं है।दूसरी तरफ एक प्रदाता के माध्यम से एक @transactional प्रबंधक के भीतर इकाई प्रबंधक प्राप्त करने वास्तव में इस समस्या को हल नहीं करता है।

चूंकि हम वास्तव में जल्द ही उत्पादन में आगे बढ़ रहे हैं, इसलिए मैंने वसंत में वापस स्विच किया है, जो शर्म की बात है, लेकिन हमारी समय सीमा का प्रबंधन करने का एकमात्र समझदार समाधान था।

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