स्थिति
मैं एक DiscriminatorColumn
, एकल तालिका भाग के लिए कॉन्फ़िगर के साथ एक इकाई है:DiscriminatorColumn/आईडी
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="TYPE")
public class ContainerAssignment{
...
}
'ContainerAssignment' एक और इकाई के लिए एक संदर्भ है:
@JoinColumn(name="CONTAINER_ID")
private Container container;
एक कंटेनर में प्रत्येक प्रकार के ContainerAssignment
हो सकते हैं। इसका मतलब है कि ContainerAssignment
तालिका की प्राथमिक कुंजी CONTAINER_ID
और TYPE
द्वारा परिभाषित की गई है।
ContainerAssignment
में कुछ उप-वर्ग हैं उदा।
@Entity
@DiscriminatorValue("SOME_TYPE")
public class SomeTypeOfContainerAssignment extends ContainerAssignment{
...
}
वहाँ केवल एक दिया CONTAINER_ID
के लिए एक एकल SomeTypeOfContainerAssignment
उदाहरण होगा।
समस्या
अगर मैं जेपीए @Id
के रूप में सिर्फ कंटेनर को परिभाषित ContainerAssignment मेज पर, मैं जो महान है entityManager.find(SomeTypeOfContainerAssignment.class, containerId)
कर सकते हैं। यह SELECT * FROM CONTAINER_ASSIGNMENT WHERE CONTAINER_ID = 1 AND TYPE = 'SOME_TYPE';
की लाइनों के साथ कुछ चलाता है। यह जानता है कि एंटीटी पर @DiscriminatorValue("SOME_TYPE")
एनोटेशन की वजह से इसे यहां टाइप प्रकार की जांच की आवश्यकता है।
हालांकि, इसका मतलब यह है कि कंटेनर से कंटेनर एस्सिग्मेंट ब्रेक के पीछे संदर्भ कंटेनर वास्तव में प्राथमिक कुंजी नहीं है। उदाहरण के लिए, यदि कंटेनर में @OneToOne(mappedBy=container) private SomeTypeOfContainerAssignment assignment;
है, जब आप किसी कंटेनर में पढ़ते हैं, तो यह टाइपिंग के बिना SELECT * FROM CONTAINER_ASSIGNMENT WHERE CONTAINER_ID = 1;
जैसे असाइनमेंट में पढ़ेगा। यह इसे एक कंटेनर के लिए सभी असाइनमेंट देता है, और उसके बाद यह गलत तरीके से यादृच्छिक रूप से यादृच्छिक रूप से चुनता है, इस मामले में, यह एक अपवाद फेंकता है।
यदि इसके बजाय, मैं कंटेनर एस्सिग्मेंटमेंट के जेपीए @Id
को कंटेनर और टाइप का उपयोग करके एक समग्र आईडी के रूप में परिभाषित करता हूं, कंटेनर एस्सिग्मेंट वर्क जुर्माना के उप-वर्गों के संदर्भ।
हालांकि, मैं entityManager.find(SomeTypeOfContainerAssignment.class, containerId)
नहीं कर सकता, क्योंकि कंटेनर आईडी नहीं है। मुझे entityManager.find(SomeTypeOfContainerAssignment.class, new MyPk(containerId, "SOME_TYPE"))
करना है, जो @DiscriminatorValue("SOME_TYPE")
के बिंदु को हराने के लिए प्रतीत होता है। अगर मैं किसी भी तरह से खोजने के लिए टाइप निर्दिष्ट करना चाहता हूं तो मैं केवल एक कंटेनर एसिग्मेंट एंटिटी का उपयोग कर सकता हूं।
प्रश्न
वहाँ जहां मेज पर प्राथमिक कुंजी discriminator स्तंभ पर समग्र है, जबकि भी बस द्वारा EntityManager.find
करने में सक्षम होने के लिए एक एकल मेज विरासत इकाई के उप-वर्गों के लिए काम कर संदर्भों के लिए एक रास्ता है प्राथमिक कुंजी का हिस्सा जो भेदभावकर्ता नहीं है?
आपके उत्तर के लिए धन्यवाद, लेकिन यह वास्तव में प्रश्न को हल नहीं करता है - क्या पीके के अंदर 'DiscriminatorColumn' kinda डालने का कोई तरीका है? मैं मानता हूं कि एक कृत्रिम पीके सबसे अच्छा विकल्प है, लेकिन कई प्रणालियों में हम स्कीमा को नियंत्रित नहीं कर सकते हैं और समग्र पीके से निपटना होगा। –
बिल कार्विन पुस्तक के मुताबिक, समग्र प्राथमिक कुंजी का उपयोग कभी भी विरोधी पैटर्न नहीं है। – atorres