2012-10-04 18 views
7

मेरे पास एक उपयोगकर्ता है जिसमें कई भूमिकाएं हैं। उपयोगकर्ता एक लिंक इकाई तालिका का उपयोग कर भूमिकाओं से जुड़ा हुआ है। जब उपयोगकर्ता को हटा दिया जाता है तो मैंने उपयोगकर्ता भूमिका लिंक इकाइयों को कैस्केड करने के लिए कॉन्फ़िगरेशन फ़ाइल सेट की है।सत्र क्यों है। OnPostUpdate में "सत्र में संभावित nonthreadsafe पहुंच" अपवाद का कारण बनता है?

हम वर्तमान में इकाइयों को हटाने के लिए सॉफ्ट डिलीट का उपयोग कर रहे हैं। हमने एक सॉफ्ट डिलीट इवेंट श्रोता जोड़ा है जो एक डिलीट द्वारा ट्रिगर किया गया है। जब कोई इकाई हटाई जा रही है, तो यह DeleteEntity ईवेंट ट्रिगर करता है जो इकाई को हटाए जाने के रूप में चिह्नित करता है।

हमने इकाई पर Evict को कॉल करके कैश से इकाइयों को हटाने के लिए OnPostUpdate ईवेंट ओवरराइड भी किया है।

यदि मैं बिना किसी भूमिका के उपयोगकर्ता बनाता हूं, तो इसे हटाएं, सब कुछ ठीक काम करता है (यह कैस्केड अक्षम होने पर भी काम करता है)। हालांकि अगर मेरे पास कम से कम एक भूमिका नियुक्त उपयोगकर्ता है और मैं OnPostUpdate में Evict को कॉल करने के बाद उपयोगकर्ता को हटा देता हूं, तो मुझे एनएचबीर्नेट अपवाद मिलता है "NHibernate.AssertionFailure: संभावित nonthreadsafe सत्र तक पहुंच"।

मैंने OnPostUpdate में, इकाई सत्र को निष्कासित करने के लिए बाल सत्र का उपयोग करने की कोशिश की है, अपवाद नहीं फेंक दिया गया है, हालांकि, इकाई को बेदखल नहीं किया गया है।

public void UserDelete(.....) 
{ 
    var user = repository.Fetch<User>(id); 

    repository.Remove(user); 
    repository.Connection.Commit(); 
} 


// soft delete event listener 
protected override void DeleteEntity(NHibernate.Event.IEventSource session, object entity, ..) 
{    
    var repositoryEntity = entity as deletableentity; 
    if (repositoryEntity != null) 
    { 
     if (!repositoryEntity.IsDeleted) 
     { 
      // this marks the entity as deleted 
      repositoryEntity.isDeleted = true; 

      // cascade delete 
      this.CascadeBeforeDelete(session, persister, repositoryEntity, entityEntry, transientEntities); 
      this.CascadeAfterDelete(session, persister, repositoryEntity, transientEntities);   
     } 
    } 
} 

public void OnPostUpdate(PostUpdateEvent @event) 
{ 
    if (@event == null) throw new ArgumentNullException("event"); 

    var entity = @event.Entity as deletableentity; 

    // Evict any entities that have been set as deleted from first level cache. 
    if (entity != null && entity.IsDeleted) 
    { 
     @event.Session.Evict(entity); 
    } 
} 

इसे हल करने के तरीके पर कोई विचार?

उत्तर

3

समस्या क्या थी। मुलायम हटाने का उपयोग वास्तव में सेट किए गए ध्वज को सेट करने के लिए अद्यतन को ट्रिगर करेगा। एक मानचित्रण

cascade="all" 

में इस लाइन की वजह से झरना के लिए दोनों अद्यतन आवेदन किया है और कार्यों बेदख़ल कर रहा है। मेरी पोस्ट अपडेट को 2 बार निकाल दिया जाएगा, लेकिन उसी समय Evict बाल संस्थाओं पर बेदखल करने की कोशिश करेगा।

समाधान मैपिंग फ़ाइल में कैस्केड से Evict को निकालना था। अब यह है:

cascade="persist, merge, save-update, delete, lock, refresh" 
+0

आपको बहुत बहुत धन्यवाद! – KeatsPeeks

1

मैं एक ही समस्या में पड़ गए, लेकिन जब से मैं धाराप्रवाह मैपिंग का उपयोग कर रहा झरना से Evict बाहर करने के लिए कोई विकल्प नहीं है। मेरे समाधान Evict बुला से बचने के लिए और सिर्फ सत्र कैश से इकाई को दूर किया गया था:

public void OnPostUpdate(PostUpdateEvent @event) 
{ 
    var entity = @event.Entity as ISoftDeletable; 
    if (entity != null && entity.Deleted) 
    { 
     IEventSource session = @event.Session; 
     IEntityPersister persister = @event.Persister; 

     var key = new EntityKey(@event.Id, persister, session.EntityMode); 
     session.PersistenceContext.RemoveEntity(key); 
     session.PersistenceContext.RemoveProxy(key); 
    } 
} 
+0

वाह मुझे विश्वास नहीं है कि हाइबरनेट को ऐसे शेंगेनियों की आवश्यकता है ... – rogerdpack

11

https://forum.hibernate.org/viewtopic.php?p=2424890 के लिए एक और तरीका यह मूल रूप से कॉल करने के लिए

  session.save(s); 
      session.flush(); // allow evict to work 
      session.evict(s); 

और वह यह है कि से बचने के अनुसार समस्या के मूल यह है कि "अगर मैंने कैश से इकाई को बेदखल कर दिया है तो प्रतिबद्ध() इसे वहां नहीं ढूंढ पाएगा" (यानी यह थ्रेड सुरक्षा समस्या नहीं है, यह एक कैश संशोधित मुद्दा था)।

+0

यह भी मेरी समस्या थी, हालांकि मैं जेपीए इंटरफ़ेस के माध्यम से हाइबरनेट का उपयोग कर रहा था और em.persist (...), em.flush() और em.detach से निपट रहा था (...)। – kilo

+3

तो मामला यह है कि "नई बनाई गई इकाई को डीबी में सहेजने से पहले सत्र से अलग (बेदखल) किया गया था" – Lu55

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