2010-08-24 12 views
14

संभव डुप्लिकेट:
Hibernate Error: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the sessionहाइबरनेट: एक ही पहचानकर्ता मूल्य के साथ विभिन्न वस्तु पहले से ही सत्र के साथ जुड़े थे

जब मैं DAO.update (userbean) का उपयोग, session.SaveOrUpdate(e); फेंक अपवाद: एक ही पहचानकर्ता मूल्य के साथ विभिन्न वस्तु पहले से ही सत्र

समारोह के साथ जुड़े थे अगले की तरह है:

public E save(E e) { 
    Session session = null; 
    try { 
     session = sessionFactory.openSession(); 
     log.debug("session="+session.hashCode()+" save "+e); 
     session.SaveOrUpdate(e); //here throws exception 
     session.flush(); 
    } 
    catch (Exception e1) { 
     log.err("Cannot open hibernate session "+ e1.getMessage()+" cause : "+e1.getCause()); 
     e1.printStackTrace(); 
    } 
    finally { if (session != null) session.close(); session = null;} 
    return e ; 
} 

userbean वर्ग का एक उदाहरण UserBean

public class UserBean{ 
    private List<GroupBean> groups = new ArrayList<GroupBean>(); 
    private List<RoleBean> roles = new ArrayList<RoleBean>(); 
} 

public class GroupBean{ 
private List<RoleBean> roles = new ArrayList<RoleBean>(); 
} 

हर groupbean भूमिकाओं है, जो न बदल रहे हैं की एक सूची है।

डेटाबेस, समूह और भूमिका में

कई-से-अनेक मानचित्रण है,

उदाहरण के लिए

,

हमारे पास एक groupbean # 1, यह की भूमिका: rolebean # 1, # 2 rolebean;

समूहबी # 2, कौन सी भूमिकाएं रोलबीन # 1 हैं।

अब मैं एक नई # 1 userbean बनाने के लिए, यह समूह है groupbean # 1 है और अगर मैं rolebean # 1 userbean # 1 जोड़ना चाहते हैं, यह शीर्षक descript

मैं देखो की तरह अपवाद फेंकता होगा server.log, और लगता है कि जब मैं उपयोगकर्ता DAO.save, saveOrUpdate आदेश है:

userbean#1 
|---|-----------***userbean.groups 
|  |  groupbean#1 
|  |   groupbean.roles 
|  |    rolebean#1 # save relebean#1 the first time 
|  |    ---done rolebean#1 
|  |   ------done all rolebeans of group.roles 
|  |  ---done groupbean#1 
|  |-----------done all groupbeans of userbean.groups 
|---|-----------***userbean.roles 
    |  rolebean#1   # save rolebean#1 the second time, and throws exception here! 
    |  ----done rolebean#1 
    |  ..... 
    |-----------done all rolebeans of userbean.roles 

अपवाद के कारण rolebean # 1 एक सत्र में दो बार सहेज लिया गया है है, और उनकी पहचान एक ही है ।

बचाने (ई ई) समारोह में, अगर मैं

session.merge(e); 

का उपयोग बदलने के

session.SaveOrUpdate(e); 

अपवाद नहीं होगा, लेकिन rolebean # 1 userbean # 1

को assocaited नहीं है

कोई भी इस बारे में कुछ सुझाव दे सकता है?

उत्तर

27

यह सही कारण की पहचान करने के हम कोड जहां दोनों उपयोगकर्ता और फिर समूह में भूमिका सेम बताए रहे हैं देख सकते हैं आसान होगा।

आम तौर पर, अपवाद हमें बताता है कि उस भूमिका बीन (दो उदाहरण) के दो संस्करण हैं। पहला अपडेट हो जाता है, फिर हाइबरनेट दूसरे को हिट करता है, और यह पहचानता है कि यह वही पहचानकर्ता है लेकिन भूमिका का एक अलग अलग संस्करण है।

हाइबरनेट के बारे में सुनिश्चित नहीं है जो सही है, और saveOrUpdate के तहत, यह एक अपवाद फेंकता आपको यह बताते हुए।

मर्ज का अनुबंध अलग-अलग काम करता है, जिसमें यह माना जाएगा कि आप इसे फिर से सहेजने के लिए चाहते हैं (यानी।, मेरे सभी परिवर्तनों को मर्ज करें), और इस प्रकार दूसरे संस्करण को दोबारा जोड़ देगा, सभी परिवर्तनों को मर्ज करें, और किसी भी अपडेट को सेव करें।

मैंने SaveOrUpdate vs Merge पर ब्लॉग किया है और कुछ और विस्तार के साथ क्या हो रहा है यह बताने के लिए।

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

अन्यथा, यदि आपके लिए विलय के प्रभाव (जो जेपीए मानक के अनुरूप है) के प्रभाव, तो इसका उपयोग करें।

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

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