2008-09-01 9 views
5
@Entity 
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) 
public class Problem { 
    @ManyToOne 
    private Person person; 
} 

@Entity 
@DiscriminatorValue("UP") 
public class UglyProblem extends Problem {} 

@Entity 
public class Person { 
    @OneToMany(mappedBy="person") 
    private List<UglyProblem> problems; 
} 

में विरासत के साथ काम नहीं करता है, मुझे लगता है कि यह स्पष्ट है कि मैं क्या करने की कोशिश कर रहा हूं। मैं @ManyToOne व्यक्ति को UglyProblem कक्षा द्वारा विरासत में रहने की उम्मीद करता हूं। लेकिन कुछ ऐसा कहने का अपवाद होगा: "ऐसी कोई संपत्ति ऐसी नहीं है जो UglyProblem क्लास (mappedBy =" person ") में पाई गई है।क्यों @OneToMany Hibernate

मुझे मिला सभी this है। मैं इमानुअल बर्नार्ड द्वारा इस पोस्ट के कारणों को समझाते हुए पोस्ट नहीं ढूंढ पाया।


दुर्भाग्य से, हाइबरनेट प्रलेखन के अनुसार, "सुपर-क्लास से गुण मैप नहीं के रूप में @MappedSuperclass अनदेखी कर रहे हैं।"

public class A { 
    private int foo; 
} 

@Entity 
public class B extens A { 
} 

तो क्षेत्ररक्षण foo वर्ग बी कौन सा समझ में आता है के लिए मैप नहीं किया जाएगा:

खैर मैं इसका मतलब है कि अगर मैं इन दो वर्गों है लगता है। लेकिन अगर मैं कुछ इस तरह है: मैं कक्षा UglyProblem फ़ील्ड id और name और दोनों वर्गों में एक ही तालिका का उपयोग मैप किया जा करने के लिए उम्मीद

@Entity 
public class Problem { 

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
private Long id; 

private String name; 

public Long getId() { 
    return id; 
} 

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

public String getName() { 
    return name; 
} 

public void setName(String name) { 
    this.name = name; 
} 
} 

@Entity 
public class UglyProblem extends Problem { 

private int levelOfUgliness; 

public int getLevelOfUgliness() { 
    return levelOfUgliness; 
} 

public void setLevelOfUgliness(int levelOfUgliness) { 
    this.levelOfUgliness = levelOfUgliness; 
} 
} 

। (वास्तव में, यह वही होता है जो मैंने किया है, मैंने अभी फिर से जांच की है)।

CREATE TABLE "problem" (
    "DTYPE" varchar(31) NOT NULL, 
    "id" bigint(20) NOT NULL auto_increment, 
    "name" varchar(255) default NULL, 
    "levelOfUgliness" int(11) default NULL, 
    PRIMARY KEY ("id") 
) AUTO_INCREMENT=2; 

मेरे सवाल करने के लिए वापस जा रहे हैं::

मैं @ManyToOne व्यक्ति UglyProblem वर्ग द्वारा विरासत में मिला होने की उम्मीद मैं इस तालिका मिला है।

मुझे उम्मीद है कि अन्य सभी मैप किए गए फ़ील्ड विरासत में हैं और मुझे कई रिश्तों के लिए यह अपवाद बनाने का कोई कारण नहीं दिख रहा है।


हाँ, मैंने देखा। वास्तव में, मैंने अपने मामले के लिए केवल पढ़ने के लिए समाधान का उपयोग किया। लेकिन मेरा सवाल था "क्यों ..." :)। मुझे पता है कि हाइबरनेट टीम के एक सदस्य द्वारा दी गई एक स्पष्टीकरण है। मैं इसे खोजने में सक्षम नहीं था और इसलिए मैंने पूछा।

मैं इस डिजाइन निर्णय की प्रेरणा जानना चाहता हूं।

(यदि आप रुचि रखते हैं कि मुझे इस समस्या का सामना करना पड़ा है: मुझे हाइबरनेट 3 का उपयोग करके निर्मित एक परियोजना विरासत में मिली। यह जेबॉस 4.0 था। कुछ + हाइबरनेट पहले से ही था (आप इसे सभी एक साथ डाउनलोड करेंगे)। मैं इस प्रोजेक्ट को ले जा रहा था Jboss 4.2.2 और मुझे पता चला है कि वहाँ विरासत में मिला रहे की "@OneToMany mappedBy" मैपिंग और यह पुराने सेटअप पर ठीक काम किया ...)

+0

आप 4 सितंबर को अपने संपादित के बारे में अधिक जानकारी के जोड़ने चाहिए:

क्या काम करता है, हालांकि बहुत साफ नहीं, @OneToMany संघ को हाइबरनेट मालिकाना @Where खंड जोड़ने के लिए क्वेरी में टाइप मजबूर करने के लिए है।केवल @OneToMany (mappedBy = "person") में सूची के बजाय सूची निर्दिष्ट करें, मैपिंग समस्या की प्रकृति को बदलती है, क्योंकि मुझे लगता है कि हमने पहले माना था कि आप समस्याओं की सूची में किसी व्यक्ति को मानचित्र बनाना चाहते हैं (Ugl –

उत्तर

4

मुझे लगता है कि यह हाइबरनेट टीम द्वारा एक बुद्धिमान निर्णय है। वे कम अहंकारी हो सकते हैं और इसे स्पष्ट कर सकते हैं कि इसे इस तरह क्यों लागू किया गया था, लेकिन यह ठीक है कि इमानुअल, क्रिस और गेविन कैसे काम करते हैं। :)

चलिए समस्या को समझने की कोशिश करते हैं। मुझे लगता है कि आपकी अवधारणाएं "झूठ बोल रही हैं"। फ़र्ट्स आप कहते हैं कि कई समस्या एस से संबंधित हैं। लेकिन, फिर आप कहते हैं कि एक व्यक्ति में कई UglyProblem s (और अन्य समस्या से संबंधित नहीं है)। उस डिजाइन में कुछ गड़बड़ है।

कल्पना कीजिए कि यह डेटाबेस में कैसे मैप किया जा रहा है। तुम बहुत एक एकल तालिका विरासत है,:

  _____________ 
      |__PROBLEMS__|   |__PEOPLE__| 
      |id <PK>  |   |   | 
      |person <FK> | -------->|   | 
      |problemType |   |_________ | 
      -------------- 

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

पुनश्च .: बदसूरत ड्राइंग के लिए खेद है: डी

1

मैं तुम्हें के साथ अपने समस्या सुपर स्तरीय टिप्पणी करने की जरूरत है@Entity के बजाय।

4

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

@MappedSuperclass 
public abstract class AbstractProblemImpl implements Problem { 
    @ManyToOne 
    private Person person; 

    public Person getPerson() { 
     return person; 
    } 
} 

@Entity 
public class ProblemImpl extends AbstractProblemImpl implements Problem { 
} 

@Entity 
public class UglyProblemImpl extends AbstractProblemImpl implements UglyProblem { 
} 

एक अतिरिक्त लाभ के रूप में,:

public interface Problem { 
    public Person getPerson(); 
} 

public interface UglyProblem extends Problem { 
} 

तो एक सार सुपर क्लास और दो इकाई उपवर्गों का उपयोग कर इन इंटरफेस को लागू:

अपने मामले में, आपको निम्न निर्धारित कर सकते हैं उन इंटरफेस को लागू करने वाले वास्तविक इकाई सेम की बजाय इंटरफेस, बाद में अंतर्निहित मैपिंग को बदलना आसान बनाता है (संगतता को तोड़ने का कम जोखिम)।

0

मैं पता लगा कि कैसे OneToMany mappedBy समस्या क्या करना है।

मूल पोस्ट से व्युत्पन्न क्लास UglyProblem में। कॉलबैक विधि व्युत्पन्न कक्षा में होनी चाहिए जो मूल वर्ग नहीं है।

@Entity 
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) 
@ForceDiscriminator 
public class Problem { 

} 

@Entity 
@DiscriminatorValue("UP") 
public class UglyProblem extends Problem { 
    @ManyToOne 
    private Person person; 
} 

@Entity 
public class Person { 
    @OneToMany(mappedBy="person") 
    private List<UglyProblem> problems; 
} 

कम से कम हाइबरनेट का उपयोग करने के लिए गुप्त सॉस मिला। http://docs.jboss.org/hibernate/stable/annotations/api/org/hibernate/annotations/ForceDiscriminator.html @ForceDiscriminator @OneToMany को भेदभावकर्ता

को हाइबरनेट एनोटेशन की आवश्यकता है।

5

मेरे मामले में मैं SINGLE_TABLE विरासत प्रकार का उपयोग करना चाहता था, इसलिए @MappedSuperclass का उपयोग करना एक विकल्प नहीं था।

@OneToMany(mappedBy="person") 
@Where(clause="DTYPE='UP'") 
private List<UglyProblem> problems; 
+0

विकल्प ' @cl'se ग्रहण या सामान्य रूप से जेपीए की सराहना की जाएगी – Odys

+0

हाय ओडिज़, एक्लिप्ससेंक में आपको बस कुछ भी निर्दिष्ट करने की आवश्यकता नहीं है। हाइबरनेट सामान्य रूप से आपको लक्ष्य के लिए एक एंटीनेशन = Person.class में निर्दिष्ट करने के लिए मजबूर करता है। तो जब आपके पास फ़ील्ड 1 के साथ इकाई। UglyPerson uglyPerson; और field2 BeutifulPerfoson beutifulPerson; eclipselink में, वह स्वचालित रूप से अपने BeuftifulPerson @DescriminatorValue ("PRETTY_PERSON") को देखने और सही सामग्री लाने के लिए जानता है। हाइबरनेट इसे नहीं जानता है, और आपको @ जहां खंड। Eclipselink एक वर्ग hiearchy का विश्लेषण और चालू करने पर smarted है eToMany मैपिंग। – 99Sono

+0

Ecliipselink में बस यह सुनिश्चित कर लें कि आपकी संस्थाएं जो कक्षा वर्ग के हिस्से का हिस्सा हैं, उनमें से प्रत्येक का अपना उचित अधिकार है; @DiscriminatorColumn (नाम = "ENTITY_CLASS", descriminatorType = स्ट्रिंग) और आप आसानी से @Inheritance (SINGLE_TABLE) हाइबरनेट साथ उपयोग कर सकते हैं, अगर की तरह अपने इकाई कुछ @DiscriminatorValue ("BEAUTIFUL_PERON") descriminator और आधार वर्ग को जोड़ने के आप इस पर काफी अटक गए हैं, क्योंकि आपको WHERE क्लैज्यूज निर्दिष्ट करने की आवश्यकता है, और पदानुक्रम में प्रत्येक बच्चे तत्व के लिए ENTITY_CLASS के साथ पूर्वानुमान को लगातार बनाए रखें। तो यहां eclipselink आगे रास्ता है। – 99Sono

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