मैं अनुभव हासिल करने के लिए हाइबरनेट के साथ प्रयोग कर रहा हूं। Student
और Worker
:हाइबरनेट: उप-वर्ग में इस मैपिंग के साथ क्या गलत है विदेशी कुंजी पर शामिल हो गए?
public abstract class Person {
private Long id;
...
}
public class Student extends Person { ... }
एक अन्य वर्ग, Employer
, Worker
के साथ एक द्विदिश एक-से-कई संबंध नहीं है मैं दो उपवर्गों के साथ एक कक्षा Person
बनाया।
public class Worker extends Person {
private Employer employer;
...
}
public class Employer {
private String taxId;
private Set<Worker> employees = new HashSet<Worker>();
...
}
जिसके लिए मानचित्रण
<class name="Employer" table="EMPLOYER">
<id name="taxId" column="TAX_ID" length="11">
<generator class="assigned"/>
</id>
...
<set name="employees" inverse="true">
<key column="EMPLOYER_TAX_ID"/>
<one-to-many class="Worker"/>
</set>
</class>
वंशानुगत पदानुक्रम एक मिश्रित रणनीति, जहां Student
PERSON
मेज पर मैप किया गया है के साथ मॉडलिंग की है, लेकिन Worker
अपनी ही तालिका में संग्रहीत किया जाता है, एक साथ शामिल हो गए विदेशी कुंजी:
<class name="Person" table="PERSON">
<id name="id" column="PERSON_ID" type="long" unsaved-value="0">
<generator class="native"/>
</id>
<discriminator column="PERSON_TYPE" type="string"/>
...
<subclass name="Student" discriminator-value="STU"> ... </subclass>
<subclass name="Worker" discriminator-value="WRK">
<join table="WORKER">
<key column="WORKER_ID"/>
<many-to-one name="employer" column="EMPLOYER_TAX_ID" cascade="save-update"/>
...
</join>
</subclass>
</class>
मैं अपाचे डर्बी 10.5.3.0 का उपयोग करें औरकी स्थापना करके स्कीमा autogenerate 0 से create-drop
।
यह सब परीक्षण करने के लिए, मैं निम्नलिखित डाटासेट के साथ एक DBUnit परीक्षण बनाया:
<EMPLOYER TAX_ID = "1234567890"
...
/>
<PERSON PERSON_ID = "12345"
PERSON_TYPE = "WRK"
...
/>
<WORKER WORKER_ID = "12345"
EMPLOYER_TAX_ID = "1234567890"
...
/>
मैं एक परीक्षण है जो कार्यकर्ता इकाई को लोड करता है और यह सत्यापित करें कि वह सही कर्मचारी है कि है। यह गुजरता है तो विपरीत दिशा के लिए एक परीक्षण:
String taxId = "1234567890";
Employer employer = (Employer) session.get(Employer.class, taxId);
assertNotNull(employer);
assertThat(employer.getEmployees().size(), is(1));
निष्पादन पर, पिछले ज़ोर विफल रहता है क्योंकि कर्मचारियों के सेट खाली है।
गहरी खुदाई, मैंने पाया कि किसी कारण के लिए हाइबरनेट के लिए तालिका व्यक्ति में बजाय कार्यकर्ता का लग रहा है (और बनाता है) EMPLOYER_TAX_ID स्तंभ! यह वर्कर में भी मौजूद है, लेकिन उस प्रश्न में इसका उपयोग नहीं किया जाता है। कर्मचारियों के सेट को पॉप्युलेट करने के लिए चुनिंदा बयान है:
select
employees0_.EMPLOYER_TAX_ID as EMPLOYER10_1_,
employees0_.PERSON_ID as PERSON1_1_,
employees0_.PERSON_ID as PERSON1_1_0_,
employees0_.FIRST_NAME as FIRST3_1_0_,
employees0_.FAMILY_NAME as FAMILY4_1_0_,
employees0_.DATE_OF_BIRTH as DATE5_1_0_,
employees0_.HOME_ADDRESS as HOME6_1_0_,
employees0_.CITY as CITY1_0_,
employees0_.ZIP as ZIP1_0_,
employees0_1_.EMPLOYER_TAX_ID as EMPLOYER2_2_0_,
employees0_1_.JOB_TITLE as JOB3_2_0_,
employees0_1_.JOB_GRADE as JOB4_2_0_,
employees0_1_.START_DATE as START5_2_0_
from
PERSON employees0_
inner join
WORKER employees0_1_
on employees0_.PERSON_ID=employees0_1_.WORKER_ID
where
employees0_.EMPLOYER_TAX_ID=?
यह क्यों है? और मैं वर्कर तालिका में EMPLOYER_TAX_ID को हाइबरनेट कैसे ढूंढ सकता हूं?
ध्यान दें कि चूंकि यह एक प्रयोगात्मक प्रोजेक्ट है, इसलिए मैं बस कुछ भी बदल सकता हूं। मैं किसी भी कामकाज की सराहना करता हूं, लेकिन मैं यह समझना पसंद करूंगा कि क्या हो रहा है और इस मैपिंग को ठीक कर रहा है (जितना संभव हो)।
अद्यतन: यदि मैं एक साफ <joined-subclass>
विरासत मैपिंग रणनीति पर स्विच करता हूं, तो जेनरेट की गई स्कीमा दिखती है और परीक्षण पास हो जाता है। यह एक अच्छा कामकाज है, लेकिन मैं अभी भी उत्सुक हूं कि मिश्रित रणनीति को सही तरीके से काम करने का कोई तरीका है या नहीं।
यदि आप जेपीए एनोटेशन का उपयोग कर सकते हैं तो अभी भी उन ग़लत XML फ़ाइल का उपयोग क्यों करें? – Kdeveloper
@Kdeveloper हमारी वास्तविक परियोजना एक्सएमएल का उपयोग करती है, इसलिए यह मेरा मुख्य लक्ष्य है जिसका प्रयोग करना है। लेकिन मैं भविष्य में एनोटेशन के लिए अपनी पालतू परियोजना का विस्तार करूंगा, क्योंकि समय की अनुमति देता है ... –
बस बाद के संदर्भ के लिए, एक से कई बिडरेक्शनल रिलेशनशिप एनोटेशन का उपयोग करके परिभाषित किया जाएगा: '@OneToMany (mappedBy =" nameOfSingleInstanceInOtherEntity ")' \t '@ManyToOne @JoinColumn (name =" nameWhichYouWishToGiveToIdField ")' –