2012-09-23 13 views
7

हाय हाइबरनेट दस्तावेज पढ़ रहा हूं।कई हाइबरनेट विपरीत पक्षों को अनदेखा किया गया

http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html

एक कई-से-अनेक संघ तार्किक @ManyToMany एनोटेशन का उपयोग कर परिभाषित किया गया है। आपको @JoinTable एनोटेशन का उपयोग करके एसोसिएशन टेबल और शर्तों में शामिल होने का भी वर्णन करना होगा। संघ द्विदिश है, तो एक तरफ मालिक हो गया है और एक तरफ उलटा अंत हो गया है (यानी जब रिश्ता संघ तालिका में मान अपडेट यह नजरअंदाज कर दिया जाएगा।):

मैं सब कुछ समझें लेकिन अंतिम

(यानी एसोसिएशन तालिका में रिलेशनशिप मान अपडेट करते समय इसे अनदेखा कर दिया जाएगा)।

इसका क्या अर्थ है? उदाहरण?

उत्तर

22

मान लीजिए आप निम्नलिखित संस्थाओं है:

@Entity 
public class Student { 
    @ManyToMany 
    private Set<Course> courses; 
    ... 
} 

@Entity 
public class Course { 
    @ManyToMany(mappedBy = "courses") 
    private Set<Student> students; 
    ... 
} 

मालिक पक्ष छात्र है (क्योंकि यह mappedBy विशेषता नहीं है)। । उलटा पक्ष पाठ्यक्रम ((क्योंकि यह mappedBy विशेषता) है

यदि आप करते हैं निम्नलिखित है:

Course course = session.get(Course.class, 3L); 
Student student = session.get(Student.class, 4L); 
student.getCourses().add(course); 

हाइबरनेट क्योंकि आप अपडेट छात्र 4 और तालिका में शामिल होने में कोर्स 3 के लिए एक प्रवेश जोड़ देगा संघ के मालिक पक्ष (student.courses)

जबकि यदि आप निम्न कार्य करें:।

Course course = session.get(Course.class, 3L); 
Student student = session.get(Student.class, 4L); 
course.getStudents().add(student); 

कुछ नहीं होगा, हो सकता है क्योंकि आपने एसोसिएशन के विपरीत पक्ष को अपडेट किया है (course.students), लेकिन स्वामी पक्ष को अपडेट करने के लिए उपेक्षित। हाइबरनेट केवल मालिक पक्ष को मानता है।

+0

धन्यवाद! बहुत अच्छी व्याख्या। तो मालिक को अद्यतन करने का एकमात्र तरीका है? दोनों पक्ष मालिक नहीं हो सकते हैं? अगर मैं इसे दोनों तरीकों से काम करना चाहूंगा तो कैसे? संभव नहीं? – pethel

+0

हां, आपको मालिक की तरफ अपडेट करना होगा। केवल एक तरफ मालिक हो सकता है। इसे दोनों तरीकों से काम करने का कोई तरीका नहीं है। –

+0

@JBNizet, और आप नीचे दिए गए उत्तर के बारे में क्या कहते हैं ?? – azerafati

2

इसे दोनों तरीकों से काम करने के लिए आपको अपनी संस्थाओं के बीच दो अलग-अलग संबंध होने की आवश्यकता है। इसे डेटाबेस में एक तालिका में शामिल किया जा सकता है लेकिन डिफ़ॉल्ट रूप से इसे दो द्वारा दर्शाया जाएगा ताकि आपको स्पष्ट रूप से कहना होगा कि आप तालिका में शामिल होना चाहते हैं।

मैं इसे छात्र और पाठ्यक्रम के पहले उल्लिखित मॉडल का उपयोग करके प्रदर्शित करूंगा। एक रिश्ते का> कोर्स संबंध मालिक जा रहा है -

@Entity 
public class Student { 
    @ManyToMany 
    @JoinTable(name = "student_course", 
       joinColumns = {@JoinColumn(name = "courses_id")}, 
       inverseJoinColumns = {@JoinColumn(name = "students_id")}) 
    private Set<Course> courses; 
    ... 
} 

@Entity 
public class Course { 
    @ManyToMany 
    @JoinTable(name = "student_course", 
       joinColumns = {@JoinColumn(name = "students_id")}, 
       inverseJoinColumns = {@JoinColumn(name = "courses_id")}) 
    private Set<Student> students; 
    ... 
} 

ऊपर के उदाहरण में हम छात्र < के प्रत्येक पक्ष के साथ 2 रिश्ते हैं। तो यह केवल मालिक के पक्ष में डेटाबेस में परिवर्तनों को सहेजने की समस्या हल करता है क्योंकि प्रत्येक पक्ष एक संबंध का मालिक होता है।

लेकिन हमें एक तथ्य यह ध्यान में रखना होगा कि डेटा सहेजने के बाद, रिलेशनशिप संग्रह डेटाबेस से पुनः लोड नहीं किया जाएगा, इसलिए प्रोग्रामर को अपने आप रिलेशनशिप संग्रह को संभालने की आवश्यकता है।इस कह कर मैं कहना है कि सबसे आसान तरीका है इस तरह संस्थाओं के बीच चक्र के पुनर्निर्माण के लिए संबंध संग्रह के लिए संशोधित setters है चाहता हूँ:

public void setCourses(Set<Course> courses) { 
    for(Course c : courses) { 
     if (!c.getStudents().contains(this)) { 
      c.getStudents().add(this); 
     } 
    } 
    this.courses = courses; 
} 

public void setStudents(Set<Student> students) { 
    for(Student s : students) { 
     if (!s.getCourses().contains(this)){ 
      s.getCourses().add(this); 
     } 
    } 
    this.students = students; 
} 
संबंधित मुद्दे