2012-03-02 11 views
37

मैं बाल entites ir से ParentEntities संदर्भित के बारे में एक प्रश्न पूछना चाहते हैं तो मैं कुछ इस तरह है:जेपीए @OneToMany -> जनक - बाल संदर्भ (विदेशी कुंजी)

Parent.java:

@Entity(name ="Parent") 
public class Parent { 
    @Id 
    @Generate..... 
    @Column 
    private int id; 

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "parent") 
    private Set<Child> children; 

    simple ... getter and setter ... 
} 

और Child.java:

@Entity(name ="Child") 
public class Child{ 
    @Id 
    @Generate.... 
    @Column 
    private int id; 

    @ManyToOne 
    private Parent parent; 

    ... simple getter an setter 
} 

निम्न तालिकाओं बनाया जा जा रहे हैं:

Parent: 
    int id 

Child: 
    int id 
    int parent_id (foreign key: parent.id) 

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

@Transactional 
public void test() { 
    Parent parent = new Parent(); 

    Child child = new Child(); 
    Set<Child> children = new HashSet<Child>(); 
    children.add(child); 

    parent.setChildren(children); 
    entityManager.persist(parent); 
    } 

जो डाटाबेस में इस की ओर जाता है:

Parent: 
    id 
    100 

Child 
    id  paren_id 
    101 100 

लेकिन मामला नहीं thats, आप स्पष्ट रूप से करने के लिए है बाल (जो, मुझे लगता है कि होता है, ढांचा शायद द्वारा कर सकता करने के लिए माता पिता के सेट अपने आप)।

तो सच में डेटाबेस में यह है क्या:

Parent: 
    id 
    100 

Child 
    id  paren_id 
    101 (null) 

कारण मैं बच्चे को जनक सेट नहीं किया है। तो मेरा प्रश्न:

क्या मुझे वास्तव में sth करना है। इस तरह?

Parent.java:

... 
setChildren(Set<Child> children) { 
    for (Child child : children) { 
    child.setParent.(this); 
    } 

    this.children = children; 
} 
... 

संपादित करें:

तेजी से जवाब के अनुसार मैं संदर्भ-स्वामित्व इकाई पर @JoinColumn का उपयोग करके इस समस्या को हल करने में सक्षम था। अगर हम ऊपर से उदाहरण लेते हैं, तो मैंने sth किया था। इस तरह:

Parent.java:

@Entity(name ="Parent") 
    public class Parent { 
     @Id 
     @Generate..... 
     @Column 
     private int id; 

     @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
     @JoinColumn(name= "paren_id") 
     private Set<Child> children; 

     simple ... getter and setter ... 
    } 

और Child.java:

@Entity(name ="Child") 
public class Child{ 
    @Id 
    @Generate.... 
    @Column 
    private int id; 

    ... simple getter an setter 
} 

अब हम ऐसा करते हैं:

@Transactional 
public void test() { 
    Parent parent = new Parent(); 

    Child child = new Child(); 
    Set<Child> children = new HashSet<Child>(); 
    children.add(child); 

    parent.setChildren(children); 
    entityManager.persist(parent); 
    } 

संदर्भ सही ढंग से सेट किया गया है अभिभावक:

Parent: 
    id 
    100 

Child 
    id  paren_id 
    101 100 

उत्तर के लिए धन्यवाद।

+0

** क्या आपके पास बच्चे की इकाई पर अभिभावक है? ** यदि हां, तो उन्होंने कैसे कॉन्फ़िगर किया।किसी भी माता-पिता के साथ मुझे त्रुटि मिलती है (_StaleStateException: बैच अपडेट अद्यतन से अप्रत्याशित पंक्ति गणना लौटाता है [0]; वास्तविक पंक्ति गणना: 0; अपेक्षित: 1_)। अगर मैं बिना किसी एनोटेशन के माता-पिता जोड़ता हूं तो यह त्रुटि भी दिखाता है (मैपिंग त्रुटि)। बच्चे के मूल क्षेत्र पर @manytoone सेटिंग के साथ मुझे सहेजने में त्रुटि मिलती है (_ORA-00904: "REPORT_REPORT_ID": недопустимый идентификатор_)। आईडी पर मेरा एफके और उसका पीके report_id नाम है लेकिन मुझे नहीं पता कि report_report_id कहां आता है। – Erlan

+0

(एक्लिप्ससेंक जेपीए कार्यान्वयन का उपयोग करना)। यह ध्यान देने योग्य है कि आपको अभी भी @ कॉलम (नाम = "paren_id") निजी लंबे माता-पिता की आवश्यकता है; इस wot काम के लिए अपने बच्चे पर मैपिंग। – AfterWorkGuinness

उत्तर

12

क्या मुझे वास्तव में sth करना है। इस तरह?

यह एक रणनीति है, हां।

द्वि-दिशात्मक संबंधों पर संबंधों का "स्वामित्व" और "गैर-स्वामित्व" पक्ष होता है। चूंकि आपके मामले में स्वामित्व पक्ष Child पर है, इसलिए इसके लिए रिश्ते को बनाए रखने की आवश्यकता है। स्वामित्व पक्ष आमतौर पर @JoinColumn निर्दिष्ट करता है, लेकिन ऐसा लगता है कि आप उस एनोटेशन का उपयोग नहीं कर रहे हैं, इसलिए यह एनोटेशन में mappedBy का उपयोग करने की संभावना से अनुमान लगाया जा रहा है।

आप read a lot more about this here कर सकते हैं।

3

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

जेपीए 2 में।0 विनिर्देश इस इन शब्दों के साथ कहा गया है:

ध्यान दें कि यह अनुप्रयोग है कि के लिए जिम्मेदारी रन-टाइम की निरंतरता को बनाए रखने भालू है रिश्तों-उदाहरण के लिए, बीमा है कि "एक" और "कई के लिए "बिडी-रेक्शनल रिलेशनशिप के पक्ष एक दूसरे के साथ संगत होते हैं जब अनुप्रयोग रनटाइम पर रिश्ते को अपडेट करता है।

1

ऊपर दिखाए गए जैसा एक साधारण ऑब्जेक्ट ग्राफ़ जारी रखते हुए हम एक समस्या में भाग गए। एच 2 में चलने से सब कुछ काम करेगा, लेकिन जब हम माईएसक्यूएल के खिलाफ भाग गए थे तो बच्चे की मेज में "paren_id" (@JoinColumn एनोटेशन में परिभाषित) माता-पिता की जेनरेट आईडी के साथ पॉप्युलेट नहीं हो रहा था - भले ही इसे गैर- डीबी में एक विदेशी कुंजी बाधा के साथ पूर्ण कॉलम।

हम इस तरह एक अपवाद मिल चाहते हैं:

org.hibernate.exception.GenericJDBCException: फील्ड 'paren_id' एक डिफ़ॉल्ट मान

किसी और को जो इस में आ सकते हैं के लिए नहीं है, क्या , (, नाम = "paren_id" नल = false)

@JoinColumn

0

अगर मैं तुम्हें सही ढंग से हो रही है के अनुसार: हम अंत में है कि हम @JoinColumn के लिए एक और विशेषता पाने के लिए किया था यह काम करने के लिए था पाया EntityManager, यदि यो आप इसे लेनदेन के सम्मिलित आदेश का प्रबंधन करना चाहते हैं, आपको "उसे बताएं" है कि इसे बच्चों को भी जारी रखना चाहिए। और आप ऐसा नहीं कर रहे हैं, इसलिए "वह" नहीं जानता कि क्या बने रहना है, लेकिन आपके माता-पिता की बाल सूची खाली नहीं है, इसलिए "वह" इसे सही करता है लेकिन संग्रहित मूल्य शून्य है।

तो आप की तरह कुछ करने पर विचार करना चाहिए:

... begin, etc 
em.persist(child) 
em.persist(parent) 

क्या आप पैरेंट ऑब्जेक्ट के साथ चाहते हैं यहाँ तो प्रतिबद्ध करते हैं और इस इसी तरह के मामलों के लिए भी काम करना चाहिए।

1

यह अभी भी मामला प्रतीत होता है। माता-पिता Entity में आप आदेश कोड में कहीं बच्चे/माता-पिता संबंध स्थापित करने के लिए कोड को दोहरा से बचने के लिए

@PrePersist 
private void prePersist() { 
    children.forEach(c -> c.setParent(this)); 
} 

की तरह कुछ हो सकता है।

+0

!! अच्छा आदमी मैं 2 सप्ताह पहले अटक गया। मैं ग्राहक से भेजे गए json के लिए कोशिश करते हैं और वसंत के @RequestBody का उपयोग कर वस्तु में बदलने का तो मुझे नहीं मेरे स्वयं के द्वारा संबंध प्रबंधन करना चाहते db से बचाने - – WRDev

+0

(बच्चे को सेट माता-पिता के लिए मुझे कोई मतलब नहीं है) !!! अद्यतन करें !!! @PrePersist के बारे में लिंक (आप @EntityListener द्वारा प्रबंधित कर सकते हैं) देखें - https://www.concretepage.com/java/jpa/jpa-entitylisteners-example-with-callbacks-prepersist-postpersist-postload-preupdate-postupdate -preremove-postremove – WRDev

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