2009-06-11 11 views
10

यह एक हिब्रनेर पॉलीमोर्फिज्म प्रश्न और डेटा मॉडल डिज़ाइन प्रश्न है; वे intertwingled हैं। मैंने अतीत में में हाइबरनेट का उपयोग किया है और इसका आनंद लिया है, लेकिन कभी-कभी मुझे कुछ भी नहीं बल्कि छोटे डिजाइनों के बारे में सोचना मुश्किल लगता है। हाइबरनेट पर दस्तक नहीं; बस एक अवलोकन है कि आम तौर पर ओआरएम चुनौतीपूर्ण हो सकता है।हाइबरनेट पॉलीमोर्फिज्म

मुझे लगता है कि यह एक हाइबरनेट 101 प्रश्न है, लेकिन मुझे यकीन नहीं है। जो मैं हासिल करने की कोशिश कर रहा हूं वह भी संभव नहीं हो सकता है।

मेरे पास एक अमूर्त वर्ग फल है जिसे ऐप्पल और ऑरेंज में उपclassed जाएगा। मेरे पास नोट नोट है जो एप्पल और संतरे के बारे में नोट्स या टिप्पणियों का प्रतिनिधित्व करता है। एक ऐप्पल या ऑरेंज में इसके साथ जुड़े कई नोट्स हो सकते हैं, लेकिन किसी दिए गए नोट से जुड़े केवल एक ऐप्पल या ऑरेंज कभी भी होगा।

यहां कक्षाओं के स्केच हैं, जहां मैं अब ऑब्जेक्ट आईडी के जाने और एप्पल के गुणों को छोड़कर को ऑरेंज से अलग करता हूं। समय के लिए, मैं दृढ़ता से महसूस नहीं करता कि मैं किस हाइबरनेट विरासत रणनीति का उपयोग करता हूं।

abstract public class Fruit { 
} 

// Apples have notes written about them: 
public class Apple extends Fruit { 
    private Set<Note> note; 
    ... 

    @OneToMany(cascade = CascadeType.ALL) 
    public Set<Note> getNote() { 
     return note; 
    } 
} 


// Oranges have notes written about them: 
public class Orange extends Fruit { 
    private Set<Note> note; 
    ... 

    @OneToMany(cascade = CascadeType.ALL) 
    public Set<Note> getNote() { 
     return note; 
    } 
} 

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

// A note about an Apple or Orange 
public class Note { 
    private String theNote; 
    private Apple apple; 
    private Orange orange; 
    ... 

    // with the usual many to one mapping 
    @ManyToOne 
    @JoinColumn(name = "apple_id") 
    public Apple getApple() { 
     return apple; 
    } 

    // with the usual many to one mapping 
    @ManyToOne 
    @JoinColumn(name = "orange_id") 
    public Orange getOrange() { 
     return orange; 
    } 

    ... 
} 

बहरहाल, यह नोट वर्ग मुझे लगता है कि कि मैं पर मेरे डिजाइन का आधार करना चाहते है, लेकिन मुझे यकीन है कि सम्मान के साथ इस बारे में सोचने के लिए कैसे एनोटेशन और तालिका मानचित्रण हाइबरनेट करने के लिए नहीं कर रहा हूँ:

// A note about a fruit: 
public class Note { 
    private String theNote; 
    private Fruit fruit; 
    ... 
} 

जहां फल या तो ऐप्पल या ऑरेंज उदाहरण होगा।

क्या बाद में नोट क्लास, फल के संदर्भ में, जो वास्तव में एक ऐप्पल या ऑरेंज धारण करेगा, यहां तक ​​कि हाइबरनेट ओआरएम मैपिंग के साथ भी मिल जाएगा? यदि हां, तो कृपया किसी के बारे में बात कर सकते हैं।

+0

मेरे कोड को MySQL डेटाबेस पर चलने के कारण मुझे एक ही समस्या है। क्या आप मेरे संबंधित प्रश्न के साथ मेरी मदद करने के इच्छुक हैं? यहां लिंक है: http://stackoverflow.com/questions/25252541/generatedvalue-for-a-java-abstract-superclass-over-mysql – CodeMed

उत्तर

13

यह बिल्कुल संभव है। आप के बजाय सार Fruit वर्ग के साथ नोटों से संबद्ध कर सकते उन्हें कार्यान्वयन में से प्रत्येक में दोहराने की:

@Entity 
@Inheritance 
public abstract class Fruit { 
    private Set<Note> notes; 
    ... 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "fruit") 
    public Set<Note> getNotes() { 
     return notes; 
    } 
} 

@Entity 
public class Apple extends Fruit { 
    ... 
} 


@Entity 
public class Orange extends Fruit { 
    ... 
} 

@Entity 
public class Note { 
    private String theNote; 

    @ManyToOne 
    private Fruit fruit; 
    ... 
} 

एट देखा!

- टिप्पणी के आधार पर जोड़ा गया: जेपीए विरासत से निपटने के लिए कई रणनीतियों प्रदान करता है। relevant section in the Java EE tutorial आपको प्रारंभ करने में मदद करनी चाहिए।

मूल रूप से, आपके विकल्प हैं:

  • एक तालिका में सब कुछ भंडारण और एक discriminator स्तंभ का उपयोग पता करने के लिए कौन सी पंक्ति है जो प्रकार
  • एक अलग तालिका
  • में प्रत्येक ठोस वर्ग (एप्पल और नारंगी) भंडारण
  • फल तालिका

के लिए एक विदेशी कुंजी के साथ एक discriminator स्तंभ के साथ एक आम फल तालिका, और एप्पल और ऑरेंज टेबल होने एक और संपादन: नोटिस यह एक हाइबरनेट है, जेपीए प्रश्न नहीं। हालांकि, बहुत अंतर नहीं होता है, क्योंकि विकल्प समान हैं। यहां relevant section in the Hibernate docs है।

+0

अस्थायी -1: यह प्रश्न का उत्तर नहीं देता है, है ना? आपने हाइबरनेट को फल और नोट के बीच संबंधों के बारे में बताया है। आप कैसे एक ऐप्पल या ऑरेंज में फल को असंतुलित करने के बारे में बताते हैं? –

+1

@ जेसन: वास्तव में, यह करता है, और बहुत शाब्दिक रूप से। यदि आप फिर से प्रश्न पढ़ते हैं, विशेष रूप से दूसरे कोड ब्लॉक से शुरू होने वाले अंतिम पैराग्राफ, जो कोड मैं प्रदान कर रहा हूं वह वही है जो ae6rt पूछ रहा है। – Henning

+0

-1 हटा दिया गया ... क्या आप विस्तार से बता सकते हैं कि एक ऐप्पल डेटाबेस में अलग-अलग ऑरेंज से कैसे संग्रहीत होता है? –

4

यह पैटर्न हाइबरनेट आधारित डाटलियर में बहुत आम है। आंतरिक रूप से यह कैसे काम करता है, इस पर आधारित है कि किस विरासत रणनीति का उपयोग किया जाता है।

प्रति वर्ग या प्रति वर्ग वर्ग प्रति तालिका तालिका का उपयोग करते समय, प्रत्येक उपclass/वर्ग के लिए एक तालिका बनाई जाएगी। उदाहरण के लिए, आपके मामले में, आपके पास फल और ऐप्पल/ऑरेंज के बीच विदेशी कुंजी संदर्भों के साथ एक टेबल फल और दो टेबल Apple और Orange होगा। आईडी द्वारा एक फल (चाहे वह सेब या नारंगी हो) का अनुरोध करते समय, हाइबरनेट बाहरी रूप से ऐप्पल और ऑरेंज टेबल के साथ फल तालिका में शामिल हो जाएगा। फ़ील्ड को पुनर्प्राप्त करने वाली तालिका से प्रत्येक पंक्ति को ऐप्पल या ऑरेंज में बदल दिया जाएगा।

भेदभाव करने वालों का उपयोग करने की एक और संभावना है। एक एकल तालिका Fruit का उपयोग किया जाएगा जिसमें एक भेदभाव क्षेत्र होगा (उदा। fruit_type मूल्य apple और orange लेना)। इस क्षेत्र के मूल्य के आधार पर, हाइबरनेट निर्धारित करेगा कि संबंधित वस्तु एक ऐप्पल या ऑरेंज है या नहीं।

आपके मामले में, उत्सुक लोडिंग के मामले में, जब हाइबरनेट नोट ऑब्जेक्ट लोड करता है तो यह उत्सुकता से संबंधित फल लाएगा और तदनुसार ऐप्पल या ऑरेंज के उदाहरण के साथ फल क्षेत्र को पॉप्युलेट करेगा।

आलसी लाने के मामले में, फल क्षेत्र फल इंटरफेस को लागू करने वाली प्रॉक्सी होगी। जब तक वास्तविक फल क्षेत्र लोड नहीं होता है तब तक इसका प्रकार अनिश्चित नहीं होता है।

आशा है कि यह आपके कुछ प्रश्नों का उत्तर देगा।