2013-08-26 7 views
5

मैं हाइबरनेट के लिए काफी नया हूं और यह निर्धारित करने की कोशिश कर रहा हूं कि यह आपके लिए क्या करेगा और इसके लिए आपको क्या करना होगा।हाइबरनेट, स्वचालित रूप से निर्भर वस्तुओं पर बने रहें

एक बड़ा व्यक्ति उस ऑब्जेक्ट से निपट रहा है जिसमें ऐसे आश्रित हैं जो डेटाबेस में अभी तक मौजूद नहीं हैं। उदाहरण के लिए, मेरे पास एक प्रोजेक्ट ऑब्जेक्ट है जिसमें एक निर्माता फ़ील्ड शामिल है जो निर्माता ऑब्जेक्ट को इसके मान के रूप में स्वीकार करता है। डेटाबेस में मेरे पास एक mfr_id कॉलम वाला एक उत्पाद तालिका है जो निर्माता तालिका (एक काफी विशिष्ट यूनिडायरेक्शनल एक से कई रिश्तों) का संदर्भ है।

यदि उत्पाद ऑब्जेक्ट को सौंपा गया निर्माता उस डेटाबेस से संबंधित है जो पहले से ही डेटाबेस में है तो कोई समस्या नहीं है। हालांकि, जब मैं उस ऑब्जेक्ट को सहेजने या अपडेट करने का प्रयास करता हूं जो उस निर्माता को संदर्भित करता है जो अभी तक जारी नहीं है, तो ऑपरेशन अपवाद के साथ विफल रहता है।

में धागा "ऐप्लिकेशन" org.hibernate.TransientObjectException अपवाद: वस्तु को संदर्भित एक न सहेजा गया क्षणिक उदाहरण -

निस्तब्धता से पहले क्षणिक उदाहरण बचाने मैं निश्चित रूप से मैन्युअल रूप से उत्पाद के निर्माता के राज्य जाँच कर सकते हैं यह देखकर कि क्या यह आईडी फ़ील्ड शून्य है और इसे सहेजने पर इसे सहेज रहा है, लेकिन यह एक बोझिल समाधान की तरह लगता है। क्या हाइबरनेट स्वचालित रूप से आश्रितों का समर्थन करता है यदि प्रश्न में निर्भर अभी तक जारी नहीं है? यदि हां, तो मैं उस व्यवहार को कैसे सक्षम करूं? मैं मैपिंग व्यवहार को निर्दिष्ट करने के लिए नेटबीन्स (3.5, मुझे विश्वास है) और इनलाइन एनोटेशन के साथ बंडल किए गए हाइबरनेट के संस्करण का उपयोग कर रहा हूं। नीचे मेरे उत्पाद और निर्माता वर्ग हैं, जो निर्भरता को संभालने वाले हिस्सों में कटौती करते हैं। (उत्पाद फैली जाने वाली चीज़ों का जो एक बिक्री योग्य तालिका का मानचित्रण, विरासत रणनीति के रूप में शामिल हो ऐसा नहीं है कि तालिका प्राथमिक कुंजी है कि उत्पाद की पहचान होती है का उपयोग)

@Entity 
@Table (
     name="products", 
     schema="sellable" 
) 
public abstract class Product extends Sellable { 
    private Manufacturer      manufacturer; 

    @ManyToOne (fetch = FetchType.EAGER) 
    @JoinColumn (name = "mfr_id") 
    public Manufacturer getManufacturer() { 
     return this.manufacturer; 
    } 

    /** 
    * 
    * @param manufacturer 
    */ 
    public Product setManufacturer (Manufacturer manufacturer) { 
     this.manufacturer = manufacturer; 
     return this; 
    } 
} 

निर्भर निर्माता

@Entity 
@Table (
     name="manufacturers", 
     schema="sellable", 
     uniqueConstraints = @UniqueConstraint(columnNames="mfr_name") 
) 
public class Manufacturer implements Serializable { 
    private Integer   mfrId  = null; 
    private String   mfrName  = null; 

    @Id 
    @SequenceGenerator (name = "manufacturers_mfr_id_seq", sequenceName = "sellable.manufacturers_mfr_id_seq", allocationSize = 1) 
    @GeneratedValue (strategy = GenerationType.SEQUENCE, generator = "manufacturers_mfr_id_seq") 
    @Column (name="mfr_id", unique=true, nullable=false) 
    public Integer getMfrId() { 
     return mfrId; 
    } 

    private Manufacturer setMfrId (Integer mfrId) { 
     this.mfrId = mfrId; 
     return this; 
    } 

    @Column(name="mfr_name", unique=true, nullable=false, length=127) 
    public String getMfrName() { 
     return mfrName; 
    } 

    public Manufacturer setMfrName (String mfrName) { 
     this.mfrName = mfrName; 
     return this; 
    } 
} 

अद्यतन: मैं this question से निम्नलिखित का प्रयास किया, लेकिन मुझे अभी भी क्षणिक ऑब्जेक्ट अपवाद मिलता है।

@ManyToOne (fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE}) 

मैंने यह भी जांच हाइबरनेट का कौन सा संस्करण NetBeans के साथ बंडल किया जाता है, यह 3.2.5

अद्यतन 2 है: मैंने पाया कि निम्न जाहिरा तौर पर काम करने के लिए के रूप में मैं चाहता था प्रकट होता है।

@ManyToOne (fetch = FetchType.EAGER, cascade = CascadeType.ALL) 

हालांकि, मुझे संदेह है कि यह वास्तव में कैस्केड प्रकार नहीं है जिसे मैं वास्तव में चाहता हूं। यदि मैं कोई उत्पाद हटा देता हूं, तो मुझे नहीं लगता कि इसके संबंधित निर्माता को हटाने का सही कार्य है, जो मुझे विश्वास है कि अब ऐसा होगा।

मैंने एक कैस्केड प्रकार बनाने का प्रयास किया जिसमें उपलब्ध सभी प्रकार शामिल थे, लेकिन यह भी काम नहीं करता था। मुझे एक ही अपवाद मिला जब मैंने उस उत्पाद को सहेजने का प्रयास किया जिसमें इसके साथ जुड़े एक सहेजे गए निर्माता थे।

@ManyToOne (fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}) 

मैंने देखा है CascadeType.SAVE_UPDATE कई स्थानों में उल्लेख किया है, लेकिन यह है कि मोड हाइबरनेट का संस्करण NetBeans के साथ आता है में उपलब्ध हो प्रतीत नहीं होता है।

उत्तर

7

आपको कैस्केडिंग ऑपरेशंस देखना है; इस प्रकार के ऑपरेशन आपको अपने माता-पिता के आंतरिक उद्देश्य के जीवन चक्र का प्रबंधन करने की अनुमति देता है।

@ManyToOne(cascade) अगर आप Session.persist() ऑपरेशन या [email protected] उपयोग करें यदि आप नहीं जेपीए समारोह Session.saveOrUpdate() का उपयोग करें।

यह सिर्फ एक उदाहरण है अपने कोड के लिए पूर्ण दस्तावेज़ बिंदु here

के लिए, यदि आप स्वचालित रूप से Manufacturer को बचाने के लिए जब Project उपयोग की बचत करना चाहते हैं:

@ManyToOne (fetch = FetchType.EAGER, cascade = {javax.persistence.CascadeType.PERSIST}) 
@JoinColumn (name = "mfr_id") 
public Manufacturer getManufacturer() { 
    return this.manufacturer; 
} 

या

@Cascade(CascadeType.PERSIST) 
+0

मैंने आपके सुझाव की कोशिश की, लेकिन जब भी मैं ऑब्जेक्ट को सहेजने की कोशिश करता हूं तब भी मुझे क्षणिक वस्तुओं के बारे में एक ही अपवाद मिलता है। मैंने http://stackoverflow.com/questions/9032998/hibernate-cascades-object-references-an-unsaved-transient-instance-save- \t @ManyToOne (fetch = FetchType.EAGER, कैस्केड) में सुझाए गए दृष्टिकोण की भी कोशिश की = {CascadeType.PERSIST, CascadeType.MERGE}) लेकिन यह – GordonM

+0

पर काम नहीं करता है क्या आप saveOrUpdate() का उपयोग कर रहे हैं? इस मामले में आपको 'org.hibernate.annotation की आवश्यकता है। @ कैस्केड (कैस्केड टाइप टाइप। AVE_UPDATE)' –

+0

इस समय मैं केवल save() का उपयोग कर रहा हूं। जब मैं आज रात घर आऊंगा तो मैं अन्य विकल्पों को देखूंगा। – GordonM

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