2009-02-14 23 views
10

किसी सूची से किसी आइटम को हटाते समय मुझे परेशानी हो रही है। सूची को सुपरक्लास में परिभाषित किया गया है, लेकिन हाइबरनेट एनोटेशन को उप-वर्ग में संपत्ति एक्सेसर्स पर लागू किया जाता है। सुपरक्लास में दो विधियां हैं जो सूची में हेरफेर करती हैं। "एड" विधि ठीक काम करती है, लेकिन "निकालें" परिवर्तनों को जारी नहीं रखता है। मैंने अपनी कैस्केड सेटिंग्स की जांच की है, और मुझे लगता है कि चीजें सही हैं। क्या मैं ऐसा कुछ कर रहा हूं जो असंभव है। यदि नहीं, तो क्या मैं कुछ गलत तरीके से कर रहा हूं?हाइबरनेट: किसी सूची से आइटम को निकालना

यहाँ मेरी वर्ग हैं:।

@Entity 
abstract class Temporal<T> { 
    @Id 
    @GeneratedValue 
    private Long id; 

    @Version 
    private Integer version = null; 

    @Transient 
    protected List<T> content = new ArrayList<T>(); 

    public void remove(T value) { 
     // business logic ... 
     content.remove(value); 
    } 

    public void add(T value) { 
     // business logic ... 
     content.add(value); 
    } 
} 

@Entity 
@AccessType("property") 
class TemporalAsset extends Temporal<Asset> { 
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "temporal") 
    public List<Asset> getContent() { 
     return super.content; 
    } 

    protected void setContent(List<Asset> list) { 
     super.content = list; 
    } 
} 

मैं TemporalAsset वर्ग का एक उदाहरण के रूप में उपयोग (ध्यान दें कि मैं केवल व्यवहार प्रदर्शित करने के लिए "ताज़ा" विधि का उपयोग कर रहा हूँ इस प्रकार सूची सही तरीके से भी मौजूद नहीं होता अगर मैं सत्र को फ्लश या बंद करता हूं और एक नया सत्र खोलता हूं):

temporalAsset.add(value1); 
temporalAsset.getContent().size() == 1; // true 
session.update(temporalAsset); 

session.refresh(temporalAsset); 

temporalAsset.getContent().size() == 1; // true 

temporalAsset.remove(value1); 
temporalAsset.getContent().size() == 0; // true 
session.update(temporalAsset); 

session.refresh(temporalAsset); 

temporalAsset.getContent().size() == 0; // false, its 1 

धन्यवाद।

उत्तर

14

आप स्पष्ट रूप से CascadeType.DELETE_ORPHAN के रूप में झरना निर्दिष्ट करने के लिए है:

दस्तावेज़ से यह अध्याय पढ़ने लायक है।

कोशिश हाइबरनेट docs से करने के लिए

@OneToMany  
@Cascade(cascade = {CascadeType.ALL, CascadeType.DELETE_ORPHAN}, mappedBy = "temporal") 

भाग कोड बदलने के लिए: माता-पिता

बच्चे वस्तु का जीवनकाल माता पिता वस्तु के जीवन काल से घिरा है, तो यह सुनिश्चित एक पूर्ण कैस्केड टाइप टाइप और org.hibernate.annotations.CascadeType निर्दिष्ट करके जीवन चक्र वस्तु।DELETE_ORPHAN

+0

वह था! बहुत बहुत धन्यवाद – codefinger

+0

CascadeType.DELETE_ORPHAN बहिष्कृत है। क्या कोई विकल्प है? –

+5

http://nocs.jboss.org/hibernate/orm/3.5/api/org/hibernate/annotations/CascadeType.html – FoxyBOA

0

सत्र में कॉल को हटाने का प्रयास करें। ताज़ा करें()। डॉक्स से:

अंतर्निहित डेटाबेस से दिया उदाहरण के राज्य को फिर से पढ़ें। पर इसका उपयोग करने के लिए यह अचूक है कि कई व्यावसायिक कार्यों का विस्तार करने वाले लंबे समय से चलने वाले सत्र लागू करें। हालांकि, यह विधि कुछ विशेष परिस्थितियों में उपयोगी है। उदाहरण

  • जहां एक डेटाबेस ट्रिगर डालने पर वस्तु राज्य को बदल देता है या अद्यतन के लिए
  • प्रत्यक्ष एसक्यूएल एक ही सत्र
  • में एक ब्लॉब या डालने CLOB
के बाद क्रियान्वित (जैसे। एक जन अद्यतन) के बाद

http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Session.html#refresh(java.lang.Object)

यदि आप फ्लश फोन() ताज़ा() से पहले, वह भी इस समस्या को ठीक कर सकते हैं, फ्लश के बाद से () गारंटी देता है कि किसी भी लंबित एसक्यूएल को डीबी के खिलाफ निष्पादित किया जाएगा। प्रैक्टिस में मैंने लगभग किसी को भी रीफ्रेश() का उपयोग नहीं देखा है और यह आपके कोड से ऐसा नहीं दिखता है जिसकी आपको आवश्यकता है।

http://www.hibernate.org/hib_docs/v3/reference/en/html/objectstate.html

+0

मुझे केवल व्यवहार को प्रदर्शित करने के लिए ताज़ा किया गया था। व्यवहार में, फ्लशिंग सूची में बदलावों को जारी नहीं रखती है। मैं सत्र को बंद भी कर सकता हूं, एक नया सत्र खोल सकता हूं, और सूची में अभी भी इसका मूल्य है। – codefinger

0

आप सुपर क्लास में क्षणिक रूप में 'सामग्री' क्षेत्र चिह्नित किया है ( अनाथ के शब्दों को हटाने के लिए हाइबरनेट संदर्भ गाइड का संदर्भ लें)। मुझे कम से कम संदेह होगा कि इससे समस्याएं पैदा हो रही हैं। उप-वर्ग में मैपिंग के साथ, मूल रूप से आपके पास एक ही विशेषता के लिए दो विरोधाभासी मैपिंग हैं।

+0

के अनुसार @OneToOne (orphanRemoval = true) या @OneToMany (orphanRemoval = true) का उपयोग करें, आपको लगता है , लेकिन इससे कोई समस्या नहीं आती है – codefinger

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