2012-03-27 13 views
6

का उपयोग करके अलग-अलग व्यवहार मैं एक मेल इकाई को जारी रखना चाहता हूं जिसमें कुछ संसाधन (इनलाइन या अटैचमेंट) हैं। सबसे पहले मैं उन्हें एक द्विदिश संबंध के रूप में संबंधित:यूनिडायरेक्शनल या बिडरेक्शनल रिलेशनशिप

@Entity 
public class Mail extends BaseEntity { 

    @OneToMany(mappedBy = "mail", cascade = CascadeType.ALL, orphanRemoval = true) 
    private List<MailResource> resource; 

    private String receiver; 
    private String subject; 
    private String body; 

    @Temporal(TemporalType.TIMESTAMP) 
    private Date queued; 

    @Temporal(TemporalType.TIMESTAMP) 
    private Date sent; 

    public Mail(String receiver, String subject, String body) { 
     this.receiver = receiver; 
     this.subject = subject; 
     this.body = body; 
     this.queued = new Date(); 
     this.resource = new ArrayList<>(); 
    } 

    public void addResource(String name, MailResourceType type, byte[] content) { 
     resource.add(new MailResource(this, name, type, content)); 
    } 

} 

@Entity 
public class MailResource extends BaseEntity { 

    @ManyToOne(optional = false) 
    private Mail mail; 

    private String name; 
    private MailResourceType type; 
    private byte[] content; 
} 

और जब मैं उन्हें बचाया:

Mail mail = new Mail("[email protected]", "Hi!", "..."); 
mail.addResource("image", MailResourceType.INLINE, someBytes); 
mail.addResource("documentation.pdf", MailResourceType.ATTACHMENT, someOtherBytes); 
mailRepository.save(mail); 

तीन आवेषण मार डाला गया:

INSERT INTO MAIL (ID, BODY, QUEUED, RECEIVER, SENT, SUBJECT) VALUES (?, ?, ?, ?, ?, ?) 
INSERT INTO MAILRESOURCE (ID, CONTENT, NAME, TYPE, MAIL_ID) VALUES (?, ?, ?, ?, ?) 
INSERT INTO MAILRESOURCE (ID, CONTENT, NAME, TYPE, MAIL_ID) VALUES (?, ?, ?, ?, ?) 

फिर मैंने सोचा कि यह बेहतर ही उपयोग करते हुए किया जाएगा एक OneToany संबंध। बचाने के लिए कोई ज़रूरत नहीं है जो मेल हर MailResource में है:

@Entity 
public class Mail extends BaseEntity { 

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) 
    @JoinColumn(name = "mail_id") 
    private List<MailResource> resource; 

    ... 

    public void addResource(String name, MailResourceType type, byte[] content) { 
     resource.add(new MailResource(name, type, content)); 
    } 

} 

@Entity 
public class MailResource extends BaseEntity { 
    private String name; 
    private MailResourceType type; 
    private byte[] content; 
} 

जेनरेट किए गए टेबल बिल्कुल एक जैसे हैं (MailResource मेल करने के लिए एक FK है)। समस्या निष्पादित SQL है:

INSERT INTO MAIL (ID, BODY, QUEUED, RECEIVER, SENT, SUBJECT) VALUES (?, ?, ?, ?, ?, ?) 
INSERT INTO MAILRESOURCE (ID, CONTENT, NAME, TYPE) VALUES (?, ?, ?, ?) 
INSERT INTO MAILRESOURCE (ID, CONTENT, NAME, TYPE) VALUES (?, ?, ?, ?) 
UPDATE MAILRESOURCE SET mail_id = ? WHERE (ID = ?) 
UPDATE MAILRESOURCE SET mail_id = ? WHERE (ID = ?) 

यह दो अपडेट क्यों? मैं एक्लिप्ससेंक का उपयोग कर रहा हूं, क्या यह व्यवहार अन्य जेपीए प्रदाता का उपयोग हाइबरनेट के समान होगा? कौन सा समाधान बेहतर है?

अद्यतन: - अगर मैं @JoinColumn का उपयोग नहीं करते EclipseLink तीन टेबल बनाता है: मेल, MAILRESOURCE और MAIL_MAILRESOURCE। मुझे लगता है कि यह पूरी तरह से तर्क है। लेकिन @ जॉइन कॉलम के साथ इसमें केवल दो टेबल बनाने के लिए पर्याप्त जानकारी है और, मेरी राय में, केवल कोई प्रविष्टि के साथ ही सम्मिलित करें।

उत्तर

0

जेपीए के लिए संबंध जहाज के स्वामित्व वाले पक्ष को परिभाषित करके मैप किया गया है, यह संघों को संभालने का बेहतर तरीका प्रदान करता है। कॉलम में शामिल हों केवल रिलेशनशिप कॉलम को परिभाषित करता है। चूंकि जेपीए पूरी तरह से प्रतिबिंब आधारित ढांचे है, इसलिए मै मैप के लिए किए गए अनुकूलन के बारे में सोच सकता हूं क्योंकि यह इस तरह से आसान है।

+0

आप JoinColumn एनोटेशन के बजाय OneToMany की mappedBy विशेषता का उपयोग करने का सुझाव दे रहे हैं? –

+0

हां। मुझे लगता है कि यह हमेशा इस तरह से बेहतर काम करेगा। –

2

जब आप एक OneToMany में @ जॉइन कॉलम का उपयोग करते हैं तो आप जेपीए 2.0 में जोड़े गए एक नए प्रकार के मैपिंग को एक "यूनिडायरेक्शनल" परिभाषित कर रहे हैं, यह जेपीए 1.0 में समर्थित नहीं था।

यह आमतौर पर OneToMany को परिभाषित करने का सबसे अच्छा तरीका नहीं है, एक सामान्य OneToMany को मैप किए गए बाई का उपयोग करके परिभाषित किया जाता है और लक्ष्य ऑब्जेक्ट में ManyToOne होता है। अन्यथा लक्षित वस्तु को इस विदेशी कुंजी का कोई ज्ञान नहीं है, और इस प्रकार इसके लिए अलग अद्यतन है।

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

एक चौथा विकल्प भी है। आप MailResource को एंटिटी के बजाय एंबेडेबल के रूप में चिह्नित कर सकते हैं और एलिमेंट कोलेक्शन का उपयोग कर सकते हैं।

देखें, http://en.wikibooks.org/wiki/Java_Persistence/OneToMany

+0

लेकिन मुझे केवल दो टेबल जेनरेट करना चाहते हैं (मेल और मेल रिसोर्स)। अगर मैं एंबेडेबल के एलिमेंट कोलेक्शन का उपयोग करता हूं तो मुझे तीन मिलेंगे, क्या मैं नहीं? – sinuhepop

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