के लिए वसंत लेनदेन समर्थन के अजीब befaviour मुझे अपेक्षाकृत सरल उपयोग मामले पर वास्तव में अजीब व्यवहार पता चला, शायद मैं वसंत @ ट्रान्सैक्शनल प्रकृति के गहरे ज्ञान के बारे में नहीं समझ सकता, लेकिन यह है काफी दिलचस्प।जेपीए + हाइबरनेट + @ ट्रांज़ेक्शनल एनोटेशन
@Transactional
public User save(User user) {
getJpaTemplate().persist(user);
return user;
}
तो जब तक मैं एक ही वर्ग के लिए नई विधि जोड़ने है ठीक काम कर रहा था: उपयोगकर्ता getSuperUser(), इस विधि चाहिए
मैं सरल उपयोगकर्ता दाव कि वसंत JpaDaoSupport वर्ग प्रदान करता है और विधि बचाने मानक शामिल है isAdmin == सत्य के साथ उपयोगकर्ता को वापस करें, और यदि डीबी में कोई सुपर उपयोगकर्ता नहीं है, तो विधि को एक बनाना चाहिए। यही कि यह कैसे की तरह देख रहा था:
public User createSuperUser() {
User admin = null;
try {
admin = (User) getJpaTemplate().execute(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
return em.createQuery("select u from UserImpl u where u.admin = true").getSingleResult();
}
});
} catch (EmptyResultDataAccessException ex) {
User admin = new User('login', 'password');
admin.setAdmin(true);
save(admin); // THIS IS THE POINT WHERE STRANGE THING COMING OUT
}
return admin;
}
जैसा कि आप देख कोड अजीब आगे है और जब पता चला कि कोई लेनदेन बनाया गया था और सेव (व्यवस्थापक) विधि के आह्वान पर प्रतिबद्ध है और कोई नया उपयोगकर्ता नहीं था मैं बहुत उलझन में था वास्तव में @Transactional एनोटेशन के बावजूद बनाया गया।
परिणामस्वरूप हमारे पास स्थिति है: जब saveDA() विधि UserDAO क्लास के बाहर से आती है - @ ट्रांस्सेन्शनल एनोटेशन गिनती और उपयोगकर्ता सफलतापूर्वक बनाया गया है, लेकिन अगर सहेज() उसी दाओ वर्ग की अन्य विधि के अंदर से आक्रमण करता है - @ ट्रान्ससेनल एनोटेशन अनदेखा किया।
यहां मैं कैसे परिवर्तन() विधि को बदलने के लिए इसे हमेशा लेनदेन बनाने के लिए मजबूर करता था।
public User save(User user) {
getJpaTemplate().execute(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
em.getTransaction().begin();
em.persist(user);
em.getTransaction().commit();
return null;
}
});
return user;
}
जैसा कि आप देखते हैं कि मैं मैन्युअल रूप से शुरूआत करता हूं और प्रतिबद्ध करता हूं। कोई विचार?
इस तरह के गहरे स्पष्टीकरण के लिए धन्यवाद, वैसे, अगर मैं पहलू को सक्रिय करूंगा क्योंकि मुझे पता है कि पहलू गतिशील प्रॉक्सी का विकल्प है। createSuperuser को लेन-देन के रूप में चिह्नित करने के लिए यह समझ में नहीं आता है, जब तक कि मैं इसे अभी भी उसी वर्ग में getSuperUser के अंदर से आमंत्रित करता हूं, लेकिन हाँ - जब मैं getSuperUser लेनदेन को चिह्नित करता हूं - सब कुछ ठीक काम करता है – abovesun