मुझे किस एनोटेशन का उपयोग करना चाहिए: @IdClass या @EmbeddedId


128

JPA(जावा हठ एपीआई) विनिर्देश इकाई समग्र कुंजी निर्दिष्ट करने के लिए 2 अलग अलग तरीकों से है: @IdClassऔर@EmbeddedId

मैं अपनी मैपिंग संस्थाओं पर दोनों एनोटेशन का उपयोग कर रहा हूं, लेकिन यह उन लोगों के लिए एक बड़ी गड़बड़ी है जो बहुत परिचित नहीं हैं JPA

मैं समग्र कुंजियों को निर्दिष्ट करने के लिए केवल एक ही तरीका अपनाना चाहता हूं। कौन सा वास्तव में सबसे अच्छा है? क्यों?

जवाबों:


86

मुझे लगता @EmbeddedIdहै कि संभवतः अधिक क्रिया है क्योंकि @IdClassआप किसी भी क्षेत्र एक्सेस ऑपरेटर का उपयोग करके पूरे प्राथमिक कुंजी ऑब्जेक्ट तक नहीं पहुंच सकते हैं। @EmbeddedIdआप इस तरह का उपयोग कर सकते हैं:

@Embeddable class EmployeeId { name, dataOfBirth }
@Entity class Employee {
  @EmbeddedId EmployeeId employeeId;
  ...
}

यह उन क्षेत्रों की स्पष्ट धारणा देता है जो समग्र कुंजी बनाते हैं क्योंकि वे सभी एक वर्ग में एकत्रित होते हैं जो एक फ़ील्ड एक्सेस ऑपरेटर को गर्त में पहुँचाता है।

साथ एक और अंतर यह @IdClassऔर @EmbeddedIdजब यह HQL लिखने के लिए आता है:

साथ @IdClassआप लिखते हैं:

कर्मचारी ई से e.name चुनें

और @EmbeddedIdआपको लिखना होगा:

कर्मचारी ई से e.employeeId.name चुनें

आपको एक ही क्वेरी के लिए अधिक पाठ लिखना होगा। कुछ लोग यह तर्क दे सकते हैं कि यह एक अधिक प्राकृतिक भाषा से भिन्न है जैसे कि एक प्रचारित IdClass। लेकिन अधिकांश बार क्वेरी से सही समझ लेना कि किसी दिए गए क्षेत्र को समग्र कुंजी का हिस्सा है अमूल्य मदद है।


10
यद्यपि मैं ऊपर दिए गए स्पष्टीकरण से सहमत हूं, मैं एक अद्वितीय उपयोग के मामले को @IdClassभी जोड़ना चाहूंगा, भले ही मैं @EmbeddedIdज्यादातर स्थितियों में पसंद करता हूं (एंटोनियो गोनक्लेव द्वारा एक सत्र से यह जानना है। उन्होंने जो सुझाव दिया था कि हम @IdClassसमग्र मामले में उपयोग कर सकते हैं। कुंजी वर्ग सुलभ नहीं है या किसी अन्य मॉड्यूल या विरासत कोड से आता है जहां हम एक एनोटेशन नहीं जोड़ सकते हैं। उन परिदृश्यों @IdClassसे हमें एक रास्ता मिल जाएगा।
गौरव रावत

1
मुझे लगता है कि यह संभव है कि @IdClass@ गौरव द्वारा दिए गए एनोटेशन का उपयोग करने के मामले जेपीए विनिर्देश एक समग्र कुंजी बनाने के दोनों तरीकों को सूचीबद्ध करता है .. @IdClassऔर@EmbeddidId
kapad

20

यौगिक प्राथमिक कुंजी का उपयोग करने के लिए तीन रणनीतियाँ हैं:

  • इसे चिह्नित करें @Embeddableऔर अपनी इकाई वर्ग को इसके लिए एक सामान्य संपत्ति जोड़ें, जिसके साथ चिह्नित किया गया है @Id
  • इसके लिए अपनी सामान्य श्रेणी में अपनी इकाई जोड़ें, जिसके साथ चिह्नित किया गया है @EmbeddedId
  • अपने सभी क्षेत्रों के लिए अपनी इकाई वर्ग में गुण जोड़ें, उन्हें चिह्नित करें @Id, और @IdClassअपने प्राथमिक कुंजी वर्ग के वर्ग की आपूर्ति के साथ अपनी इकाई वर्ग को चिह्नित करें ।

सबसे प्राकृतिक दृष्टिकोण @Idके रूप @Embeddableमें चिह्नित एक वर्ग के साथ उपयोग । @Embeddableटैग गैर प्राथमिक कुंजी एम्बेड होने मूल्यों के लिए वैसे भी इस्तेमाल किया जा सकता। यह आपको एक ही संपत्ति के रूप में यौगिक प्राथमिक कुंजी का इलाज करने की अनुमति देता है, और यह @Embeddableअन्य तालिकाओं में कक्षा के पुन: उपयोग की अनुमति देता है ।

अगले सबसे प्राकृतिक दृष्टिकोण @EmbeddedIdटैग का उपयोग है । यहां, प्राथमिक कुंजी वर्ग को अन्य तालिकाओं में उपयोग नहीं किया जा सकता है क्योंकि यह एक नहीं है@Embeddable इकाई , लेकिन यह हमें कुछ वर्ग के एकल गुण के रूप में कुंजी का इलाज करने की अनुमति देता है।

अंत में, के उपयोग @IdClassऔर @Idएनोटेशन हमें इकाई ही प्राथमिक कुंजी कक्षा में गुण के नाम करने के लिए इसी के गुणों का उपयोग कर परिसर प्राथमिक कुंजी वर्ग मैप करने के लिए अनुमति देता है। नामों के अनुरूप होना चाहिए (इसे ओवरराइड करने के लिए कोई तंत्र नहीं है), और प्राथमिक कुंजी वर्ग को अन्य दो तकनीकों के साथ समान दायित्वों का सम्मान करना चाहिए। इस एप्रोच का एकमात्र लाभ एनक्लोजिंग इकाई के इंटरफेस से प्राथमिक कुंजी वर्ग के उपयोग को "छिपाने" की क्षमता है। @IdClassएनोटेशन कक्षा प्रकार का एक मूल्य पैरामीटर, जो वर्ग यौगिक प्राथमिक कुंजी के रूप में इस्तेमाल किया जा करने के लिए किया जाना चाहिए लगता है। प्राथमिक कुंजी वर्ग के गुणों से मेल खाने वाले फ़ील्ड को सभी के साथ एनोटेट किया जाना चाहिए @Id

संदर्भ: http://www.apress.com/us/book/9781430228509


17

मुझे एक उदाहरण मिला जहां मुझे IdClass के बजाय एंबेडेडआईड का उपयोग करना था। इस परिदृश्य में एक सम्मिलित तालिका है जिसमें अतिरिक्त स्तंभ परिभाषित हैं। मैंने IdClass का उपयोग करके इस समस्या को हल करने का प्रयास किया जो कि एक इकाई की कुंजी का प्रतिनिधित्व करती है जो स्पष्ट रूप से जॉइन टेबल में पंक्तियों का प्रतिनिधित्व करती है। मैं इसे इस तरह से काम नहीं कर सका। शुक्र है कि "Java Persistence With Hibernate" में इस विषय को समर्पित एक खंड है। एक प्रस्तावित समाधान मेरे लिए बहुत समान था, लेकिन इसके बजाय एंबेडेड आईड का उपयोग किया। मैंने अपनी वस्तुओं को उन किताबों के बाद मॉडल किया, जो अब सही ढंग से व्यवहार करती हैं।


13

जहां तक ​​मुझे पता है कि अगर आपके कंपोजिट पीके में एफके है तो यह उपयोग करने में आसान और सरल है @IdClass

इसके साथ @EmbeddedIdआपको अपने FK कॉलम के लिए दो बार मैपिंग को परिभाषित करना होगा, @Embeddedableएक बार में और एक बार यानी @ManyToOneजहाँ @ManyToOneपर केवल-पढ़ने के लिए ( @PrimaryKeyJoinColumn) होना चाहिए क्योंकि आपके पास एक कॉलम दो चर (संभावित संघर्ष) में सेट नहीं हो सकता है।
तो आपको अपने FK को सरल प्रकार का उपयोग करके सेट करना होगा @Embeddedable

@IdClassइस स्थिति का उपयोग करने वाली अन्य साइट पर OneToOne और ManyToOne संबंधों के माध्यम से प्राथमिक कुंजी में दिखाए गए अनुसार बहुत आसानी से नियंत्रित किया जा सकता है :

उदाहरण JPA 2.0 ManyToOne आईडी एनोटेशन

...
@Entity
@IdClass(PhonePK.class)
public class Phone {

    @Id
    private String type;

    @ManyToOne
    @Id
    @JoinColumn(name="OWNER_ID", referencedColumnName="EMP_ID")
    private Employee owner;
    ...
}

उदाहरण जेपीए 2.0 आईडी वर्ग

...
public class PhonePK {
    private String type;
    private long owner;

    public PhonePK() {}

    public PhonePK(String type, long owner) {
        this.type = type;
        this.owner = owner;
    }

    public boolean equals(Object object) {
        if (object instanceof PhonePK) {
            PhonePK pk = (PhonePK)object;
            return type.equals(pk.type) && owner == pk.owner;
        } else {
            return false;
        }
    }

    public int hashCode() {
        return type.hashCode() + owner;
    }
}

1
बस अपने PK वर्ग में सोना जोड़ने के लिए मत भूलना
सोनाटा

@ सोनाटा हमें गेटर्स की आवश्यकता क्यों है? मैंने इसे बिना किसी
गेटर्स

आईडी वर्ग उदाहरण के लिए धन्यवाद! हालांकि मैंने सीरियल को लागू करने की आवश्यकता भी समाप्त कर दी। साथ ही गेटर्स और सेटर भी जोड़ सकते हैं, खासकर अगर आपका आईडीई अपने आप उन्हें उत्पन्न कर सकता है।
Starwarswii

8

मुझे लगता है कि मुख्य लाभ यह है कि हम @GeneratedValueआईडी का उपयोग करते समय उपयोग कर सकते हैं @IdClass? मुझे यकीन है कि हम इसके @GeneratedValueलिए उपयोग नहीं कर सकते @EmbeddedId


1
क्या एंबेडेडिड में @GeneratedValue का उपयोग करना संभव नहीं है ??
काइसर

1
मैंने इसे एंबेडेडआईड के साथ सफलतापूर्वक उपयोग किया है, लेकिन जाहिर है कि यह समर्थन डीबी द्वारा भिन्न होता है। यह IdClass के साथ उपयोग करने के बारे में भी सच है। युक्ति कहती है: "जेनरेटवैल्यू एनोटेशन को केवल साधारण (यानी, गैर-मिश्रित) कुंजी के लिए ही उपयोग किया जा सकता है।"
BPS

4

@Idजब @EmbeddedIdउपयोग किया जाता है तो समग्र कुंजी के पास कोई संपत्ति नहीं होनी चाहिए ।


1

FROM Entity WHERE id IN :idsएंबेडेडआईड के साथ आप एचक्यूएल में इन क्लॉज का उपयोग कर सकते हैं, उदाहरण के लिए: जहां आईडी एंबेडेडआईड है, जबकि यह उसी तरह के परिणाम को प्राप्त करने के लिए दर्द होता है जब आप IdClass के साथ कुछ ऐसा करना चाहते हैंFROM Entity WHERE idPartA = :idPartA0 AND idPartB = :idPartB0 .... OR idPartA = :idPartAN AND idPartB = :idPartBN

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.