2012-02-16 14 views
5

में एम्बेड करने योग्य संग्रह में सिंगल टेबल मैपिंग मेरे पास जेपीए में एकाधिक इकाइयों को एक टेबल को मैप करने की कोशिश करने की एक बिल्कुल अनूठी स्थिति है। मैंने @Embeddable और @ElementCollection के बारे में पढ़ा है, लेकिन मुझे यकीन नहीं है कि मेरी स्थिति में उनका उपयोग कैसे करें (या यदि मैं कर सकता हूं)। एक डेटाबेस तालिका पाठ्यक्रम की जानकारी रखती है। तालिका में पंक्तियां हो सकती हैं जहां पाठ्यक्रम में सबकुछ कुछ मूल्यों को छोड़कर समान होता है, जैसे कक्ष संख्या और दिन। उदाहरण के लिए:जेपीए

TERM_CODE SUBJECT_CODE ROOM DAY INSTRUCTOR_ID 
201220  EGRE   0101 TR  123 
201220  EGRE   0103 W  124 

वहाँ एक रास्ता है कि मैं के रूप में ऊपर दो पंक्तियों से डेटा निकाल सकते हैं, और अलग वस्तुओं का संग्रह में एक वस्तु में आम डेटा और विभिन्न मूल्यों डाल है? यहाँ कैसे मैं कक्षाओं में परिभाषित करना चाहते हैं का एक उदाहरण है:

@Entity 
public class Course implements Serializable { 

    @Id 
    @Column(name = "TERM_CODE") 
    private Long termCode; 

    @Column(name = "SUBJECT_CODE") 
    private String subjectCode; 

    @Embedded 
    Collection<CourseSchedule> schedule; 

    public Long getTermCode() { 
    return termCode; 
    } 

    public void setTermCode(Long termCode) { 
    this.termCode = termCode; 
    } 

    public String getSubjectCode() { 
    return subjectCode; 
    } 

    public void setSubjectCode(String subjectCode) { 
    this.subjectCode = subjectCode; 
    } 
} 

CourseSchedule:

@Embeddable 
public class CourseSchedule { 
    private String room; 
    private String day; 

     public String getRoom() { 
     return room; 
     } 

     public void setRoom(String room) { 
     this.room = room; 
     } 

     public String getDay() { 
     return day; 
     } 

     public void setDay(String day) { 
     this.day = day; 
     } 

     public String getInstructorId() { 
     return instructorId; 
     } 

     public void setInstructorId(String instructorId) { 
     this.instructorId = instructorId; 
     } 
} 

एक बार मैं उन्हें मिल मैं भी क्या मेरी JPQL इस स्थिति में कैसा दिखेगा के रूप में उलझन में हूँ मैप किया।

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

अगर मैं TERM_CODE स्तंभ के लिए @Id जोड़ने के लिए, एक पाठ्यक्रम वस्तु हाइबरनेट त्रुटियों के बिना दिया जाता है, लेकिन CourseSchedule संग्रह है कि पाठ्यक्रम का हिस्सा है रिक्त है।

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

मैं दो अलग-अलग टेबल के रूप में पाठ्यक्रम और CourseSchedule इलाज (भले ही वे नहीं कर रहे हैं) के साथ चारों ओर खेलने के लिए कोशिश की है, लेकिन मैं उन्हें @OneToMany का उपयोग कर शामिल हो पाने के लिए नहीं कर पा रहे और @ManyToOne।

@Entity 
@IdClass(CourseId.class) 
@Table(name = "course_table") 
public class Course implements Serializable { 

    @OneToMany(mappedBy = "course") 
    private Collection<CourseSchedule> schedule; 

    @Id 
    @Column(name = "TERM_CODE") 
    private Long termCode; 

    @Id 
    @Column(name = "SUBJECT_CODE") 
    private Long subjectCode; 

    ... 
} 

@Entity 
@IdClass(CourseScheduleId.class) 
@Table(name = "course_table") 
public class CourseSchedule implements Serializable { 

    @ManyToOne 
    @JoinColumns({ 
    @JoinColumn(name="TERM_CODE", referencedColumnName="TERM_CODE"), 
    @JoinColumn(name = "SUBJECT_CODE", referencedColumnName="SUBJECT_CODE") 
    }) 
    private Course course; 

    @Column(name = "TERM_CODE") 
    private Long termCode; 

    @Column(name = "SUBJECT_CODE") 
    private Long subjectCode; 

    @Id 
    private String room; 

    @Id 
    private String day; 

    @Id 
    @Column(name = "INSTRUCTOR_ID") 
    private String instructorId; 

    ... 

} 

(CourseId और CourseScheduleId सरल समग्र आईडी के लिए इस्तेमाल किया वर्ग हैं।) के ऊपर मानचित्रण निम्न त्रुटि लौट:

org.hibernate.MappingException: Foreign key (FK82D03688F590EF27:course_table [TERM_CODE,SUBJECT_CODE])) must have same number of columns as the referenced primary key (course_table [ROOM,DAY,INSTRUCTOR_ID) 

मैं CourseSchedule कोर्स अगर वापस करने के लिए चर्चा करते हुए की जरूरत नहीं है जो इसे आसान बनाने में मदद करता है।

कोई विचार? मेरा एकमात्र अन्य विचार उन्हें पूरी तरह अलग इकाइयों (शामिल नहीं) के रूप में परिभाषित करना है, और फिर किसी भी तरह उन्हें जेपीक्यूएल का उपयोग करके एक साथ मानचित्र बनाना है।

+0

मुझे लगता है कि यह एक मौजूदा डीबी है? तो आप कोर्सशेड्यूल तालिका में TERM_CODE पर एक विदेशी कुंजी का उपयोग नहीं कर सकते हैं? मेरे पास ऐसा करने का एक अच्छा कारण हो सकता है, लेकिन आप ROOM और DAY जानकारी को स्टोर करने के लिए बस कुछ डेटा डुप्लिकेट करते हैं। जब आप इसे इस तरह मैप करते हैं तो हाइबरनेट रिपोर्ट क्या करता है? – bvanvelsen

+0

दुर्भाग्यवश मैं डेटाबेस नहीं बदल सकता, और यह सब एक ही तालिका में है। काश मैं उन्हें सामान्य करने के लिए उन्हें मनाने के लिए मना सकता हूं, लेकिन ऐसा नहीं हो रहा है। – acvcu

+0

यदि मैं इसे अपने वर्तमान रूप में चलाता हूं, तो मुझे त्रुटि मिलती है "इकाई के लिए निर्दिष्ट कोई पहचानकर्ता नहीं: कोर्स", जिसे मुझे लगभग उम्मीद करनी चाहिए थी। एक और मुद्दा यह है कि डेटाबेस तालिका प्राथमिक कुंजी को परिभाषित नहीं करती है। – acvcu

उत्तर

3

मैं कुछ चीजें कोशिश कर रहे हैं, और निकटतम मैं तुम क्या चाहते करने के लिए मिलता है इस (CourseSchedule कक्षा में सेटर setCourse जाँच):

कोर्स

@Embeddable 
public class Course implements Serializable { 

@Column(name = "TERM_CODE") 
private Long termCode; 

@Column(name = "SUBJECT_CODE") 
private String subjectCode; 

@Transient 
Collection<CourseSchedule> schedule = new ArrayList<CourseSchedule>(); 

public void setSchedule(Collection<CourseSchedule> schedule) { 
    this.schedule = schedule; 
} 
public Collection<CourseSchedule> getSchedule() { 
    return schedule; 
} 

public Long getTermCode() { 
return termCode; 
} 

public void setTermCode(Long termCode) { 
this.termCode = termCode; 
} 

public String getSubjectCode() { 
return subjectCode; 
} 

public void setSubjectCode(String subjectCode) { 
this.subjectCode = subjectCode; 
} 
} 

CourseSchedule

@Entity(name="Course") 
public class CourseSchedule { 
private String room; 
private String day; 

@Id 
@GeneratedValue 
private int id; 

public int getId() { 
    return id; 
} 

public void setId(int id) { 
    this.id = id; 
} 

@Embedded 
private Course course; 

public Course getCourse() { 
    return course; 
} 

public void setCourse(Course course) { 
    course.schedule.add(this); 
    this.course = course; 
} 

public String getRoom() { 
    return room; 
} 

public void setRoom(String room) { 
    this.room = room; 
} 

public String getDay() { 
    return day; 
} 

public void setDay(String day) { 
    this.day = day; 
} 
} 

जेनरेट की गई डेटाबेस तालिका

id subject_code term_code day room 
1  "EGRE"   201220  "TR" "0101" 
2  "EGRE"   201220  "W" "0103" 

असल में दूसरी तरफ। यह पूरी तरह से आप अपेक्षा नहीं करते हैं, लेकिन यह आपको बेहतर समाधान के लिए प्रेरित कर सकता है, अगर आपको अधिक विचार हैं या कुछ दिलचस्प पाया गया है तो कृपया मुझे अपडेट रखें ...

नक्शा ही मेज पर पाठ्यक्रम और CourseSchedule, लेकिन उन्हें शामिल नहीं है::

@Entity 
@IdClass(CourseId.class) 
@Table(name = "course_table") 
public class Course implements Serializable { 

    @Transient 
    private Collection<CourseSchedule> schedule; 

    @Id 
    @Column(name = "TERM_CODE") 
    private Long termCode; 

    @Id 
    @Column(name = "SUBJECT_CODE") 
    private Long subjectCode; 

    ... 
} 

@Entity 
@IdClass(CourseScheduleId.class) 
@Table(name = "course_table") 
public class CourseSchedule implements Serializable { 

    @Column(name = "TERM_CODE") 
    private Long termCode; 

    @Column(name = "SUBJECT_CODE") 
    private Long subjectCode; 

    @Id 
    private String room; 

    @Id 
    private String day; 

    @Id 
    @Column(name = "INSTRUCTOR_ID") 
    private String instructorId; 

    ... 

} 

में

+0

यह एक बुरा विचार नहीं है, मैं इसे एक नज़र दूंगा। एकमात्र मुद्दा यह है कि आपके पास जिस तरह से है, क्या मुझे एक और डेटाबेस तालिका उत्पन्न नहीं करनी पड़ेगी? मैंने शायद डेटाबेस को पढ़ने/लिखने के लिए उपयोग किया है, लेकिन मेरे पास डेटा नहीं है और सर्वर पर कुछ भी नया नहीं बना सकता है। यह मुझे पाठ्यक्रमों के संग्रह के रूप में कोर्सशेड्यूल रखने की अनुमति नहीं देता है, जो ग्राहक परिप्रेक्ष्य से वस्तुओं का उपयोग करते समय अधिक तार्किक अर्थ बनाता है। – acvcu

+0

मैं वापस गया और जेनरेट आईडी के बारे में यह w/आउट करने की कोशिश की, लेकिन मुझे बिना किसी कोर्स कोर्स किए गए पाठ्यक्रमों के पाठ्यक्रमों को वापस करने के लिए मेरे कोई प्रश्न नहीं मिल सका। जेनरेट आईडी का उपयोग करने के बजाय, मैंने कोर्सशेड्यूल पर एक समग्र आईडी का उपयोग किया। – acvcu

0

यह है कि मैं क्या के साथ आया था (जब तक कि कोई एक बेहतर विचार के साथ आता है) है डीएओ वस्तु, पाठ्यक्रम और CourseSchedule अलग से क्वेरी और कोर्स के लिए CourseSchedule संग्रह जोड़ें:

public Collection<Course> getCourses() { 
    String jpql = "SELECT DISTINCT course FROM Course course"; 

    TypedQuery<Course> typedQuery = entityManager 
     .createQuery(jpql, Course.class); 

    // get the Courses and set their schedules 
    Collection<Course> courses = typedQuery.getResultList(); 
    setCourseSchedules(courses); 

    return courses; 
} 

private void setCourseSchedules(Collection<Course> courses) { 
    // query for getting CourseSchedules 
    String jpql = "SELECT DISTINCT schedule FROM CourseSchedule schedule " 
      + "WHERE schedule.subjectCode = :subjectCode " 
      + "AND schedule.termCode = :termCode"; 

    for (Course c : courses) { 
     TypedQuery<CourseSchedule> typedQuery = entityManager 
       .createQuery(jpql, CourseSchedule.class) 
       .setParameter("subjectCode", c.getSubjectCode()) 
       .setParameter("termCode", c.getTermCode()); 
     c.setSchedule(typedQuery.getResultList()); 
    } 
}