2011-02-04 16 views
11

मैं वर्तमान में @PostPersist और @PostUpdate के साथ काम कर रहा हूं, और उन ट्रिगर्स में मैं अतिरिक्त संस्थाएं बना रहा हूं। सवाल यह है कि, क्या वे एक ही लेनदेन में ट्रिगर्स हैं और यदि ऐसा नहीं है तो इसे मजबूर करना संभव है?जेपीए/@ पोस्टस्टर्सिस्ट @ पोस्टस्टडेट - लेनदेन

मेरे लिए यह इस तरह से काम करता है। जबकि मैं लॉग देख रहा था, लेनदेन मौजूद नहीं है (यह ट्रिगर लॉन्च होने से ठीक पहले ही किया जाता है) जो मुझे डेटाबेस में अतिरिक्त इकाइयों को सहेजने से इंजेक्शन बीन से स्थायी विधि पर REQUIRES_NEW के बिना) रोकता है। REQUIRED विशेषता पूरी तरह से अनदेखा की जाती है, और MANDATORY विशेषता अपवाद नहीं फेंकती है।

क्या यह जुनीट के साथ समस्या हो सकती है (क्योंकि मैं देव चरण में हूं और पूर्ण env पर व्यवहार का परीक्षण नहीं किया।)?

यदि इस ट्रिगर पर लेनदेन को विस्तारित करना संभव नहीं है, तो यह सुनिश्चित करने के लिए कि यदि रोलबैक @PostPersist और @PostUpdate से पहले होता है, तो उन परिचालनों को भी रोलबैक किया जाएगा।

किसी भी मदद के लिए अग्रिम धन्यवाद,

सधन्यवाद, पी

+0

हे। जब मैं परीक्षण करता हूं, तो मुझे लगता है कि श्रोता में सभी ऑपरेशन मास्टर ऑपरेशन के समान लेनदेन में हैं। मैं श्रोता को चिह्नित करने के लिए @PostUpdate एनोटेशन का उपयोग करता हूं। – Scarlett

उत्तर

11

एक PostPersist घटना की फायरिंग का संकेत नहीं है कि संस्था एक सफल प्रतिबद्ध किया है। घटना की गोलीबारी के बाद लेनदेन को वापस ले जाया जा सकता है लेकिन सफल प्रतिबद्धता से पहले। PostPersist में आप लेन-देन में इस्तेमाल इकाई प्रबंधक और फिर इस तरह somehting करते हैं:

@PostPersist 
void someMethod() { 
    EntityManager em = null; 
    em = getEntityManagerUsedInTransaction(); 
    EntityTransaction et = em.getTransaction(); // should return the current transaction 
    if (et.isActive()) { 
    // do more db stuff 
    } 
} 

एनबी: मैं इस तो यह केवल अटकलें है (यद्यपि 'मैं जीवन भर घटना ट्रिगर का इस्तेमाल किया है प्रयास नहीं किया है अन्य सामान के लिए बड़े पैमाने पर)। मुझे यह जोड़ना है कि मुझे नहीं लगता कि यह एक अच्छा विचार है। फ्लैग करने के लिए पोस्टपर्सिस्ट का उपयोग करें कि अन्य संस्थाओं को जारी रखा जाना चाहिए और इसे दूसरे लेनदेन में करना चाहिए।

10

आप स्प्रिंग उपयोग कर रहे हैं तो आप हमेशा रजिस्टर कर सकता है अपने वर्तमान लेनदेन प्रबंधक के साथ एक TransactionSynchronization घटनाओं पर वापस बुलाया जा करने के लिए इस तरह के रूप में अपने वर्तमान में चल रहे लेनदेन के लिए प्रतिबद्ध:

@PostPersist 
void onPersist() { 
    TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { 

     @Override 
     public void beforeCommit(boolean readOnly) { 
     // do work 
     } 
    }); 
    }  
} 

एक TransactionSynchronization भी एक के बाद कॉलबैक प्रदान करता है लेनदेन सफलतापूर्वक किया गया है और लेनदेन पूरा होने से पहले/बाद में पूरा हो गया है।

यदि आपको यह जांचने की आवश्यकता है कि लेनदेन किया गया था या वापस लुढ़का गया था, तो afterCompletion(int status) का उपयोग करें।

विवरण के लिए TransactionSynchronization's JavaDoc पर एक नज़र डालें।

-1

जेपीए आंतरिक कॉलबैक विधियां आंतरिक कॉलबैक विधियां एक इकाई वर्ग के भीतर परिभाषित विधियां हैं। उदाहरण के लिए, निम्न इकाई वर्ग खाली कार्यान्वयन के साथ सभी समर्थित कॉलबैक तरीकों को परिभाषित करता है:

@Entity 
public static class MyEntityWithCallbacks { 
    @PrePersist void onPrePersist() {} 
    @PostPersist void onPostPersist() {} 
    @PostLoad void onPostLoad() {} 
    @PreUpdate void onPreUpdate() {} 
    @PostUpdate void onPostUpdate() {} 
    @PreRemove void onPreRemove() {} 
    @PostRemove void onPostRemove() {} 
} 

आंतरिक कॉलबैक तरीकों हमेशा शून्य लौट सकते हैं और कोई तर्क लेना चाहिए। उनके पास कोई नाम और कोई पहुंच स्तर (सार्वजनिक, संरक्षित, पैकेज और निजी) हो सकता है लेकिन स्थिर नहीं होना चाहिए।

एनोटेशन निर्दिष्ट करता है कॉलबैक विधि शुरू हो जाती है:

@PrePersist - before a new entity is persisted (added to the EntityManager). 
@PostPersist - after storing a new entity in the database (during commit or flush). 
@PostLoad - after an entity has been retrieved from the database. 
@PreUpdate - when an entity is identified as modified by the EntityManager. 
@PostUpdate - after updating an entity in the database (during commit or flush). 
@PreRemove - when an entity is marked for removal in the EntityManager. 
@PostRemove - after deleting an entity from the database (during commit or flush). 

एक इकाई वर्ग किसी भी सबसेट या जीवन चक्र की घटनाओं के संयोजन, लेकिन एक ही घटना के लिए एक से अधिक कॉलबैक विधि के लिए कॉलबैक तरीकों में शामिल कर सकते हैं। हालांकि, एक ही विधि का उपयोग कई कॉलबैक घटनाओं के लिए एक से अधिक एनोटेशन के साथ चिह्नित करके किया जा सकता है।

डिफ़ॉल्ट रूप से, उप-वर्ग की इकाई ऑब्जेक्ट्स के लिए एक सुपर इकाई वर्ग में एक कॉलबैक विधि भी लागू की जाती है जब तक कि कॉलबैक विधि उप-वर्ग द्वारा ओवरराइड नहीं की जाती है।

कार्यान्वयन प्रतिबंध मूल डेटाबेस ऑपरेशन के साथ संघर्ष से बचने के लिए जो इकाई जीवन चक्र घटना (जो अभी भी प्रगति पर है) को आग लगाना कॉलबैक विधियों को EntityManager या क्वेरी विधियों को कॉल नहीं करना चाहिए और किसी अन्य इकाई ऑब्जेक्ट तक नहीं पहुंचना चाहिए।

यदि कॉलबैक विधि सक्रिय लेनदेन के भीतर अपवाद फेंकता है, तो लेनदेन रोलबैक के लिए चिह्नित किया जाता है और उस ऑपरेशन के लिए कॉलबैक विधियों को और अधिक नहीं बुलाया जाता है।

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