हाइबरनेट एनोटेशन में @UniqueConstraint और @Column (अद्वितीय = सत्य)


104

@UniqueConstraint और @Column (अद्वितीय = सत्य) के बीच क्या अंतर है ?

उदाहरण के लिए:

@Table(
   name = "product_serial_group_mask", 
   uniqueConstraints = {@UniqueConstraint(columnNames = {"mask", "group"})}
)

तथा

@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private ProductSerialMask mask;

@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private Group group;

2
नोट: हाइबरनेट 5.4 के साथ, जब मैंने जोड़ा unique=true, तो स्कीम ऑटो-इंडेपेटर द्वारा इंडेक्स नहीं जोड़ा गया था। @UniqueConstraintयह दिखाई दिया। बग हो सकता है।
ओन्द्रा žižka

जवाबों:


147

जैसा कि पहले कहा गया है, @Column(unique = true)यह एक शॉर्टकट है UniqueConstraintजब यह केवल एक क्षेत्र है।

आपके द्वारा दिए गए उदाहरण से, दोनों में बहुत बड़ा अंतर है।

@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private ProductSerialMask mask;

@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private Group group;

इस कोड का तात्पर्य है कि दोनों maskऔर groupअद्वितीय होना है, लेकिन अलग से। इसका मतलब है कि यदि, उदाहरण के लिए, आपके पास एक मास्क है। आईडी = 1 और मास्क के साथ एक और रिकॉर्ड डालने की कोशिश करता है। = 1 , तो आपको एक त्रुटि मिलेगी, क्योंकि उस कॉलम में अद्वितीय मान होना चाहिए। समूह के लिए एक ही aplies।

दूसरी ओर,

@Table(
   name = "product_serial_group_mask", 
   uniqueConstraints = {@UniqueConstraint(columnNames = {"mask", "group"})}
)

लागू किया जाता है कि संयुक्त + समूह के मूल्य अद्वितीय होने चाहिए। इसका मतलब है कि आपके पास हो सकता है, उदाहरण के लिए, mask.id = 1 और group.id = 1 के साथ एक रिकॉर्ड , और यदि आप mask.id = 1 और group.id = 2 के साथ कोई अन्य रिकॉर्ड सम्मिलित करने का प्रयास करते हैं , तो इसे डाला जाएगा सफलतापूर्वक, जबकि पहले मामले में यह नहीं होगा।

यदि आप मास्क और समूह दोनों को अलग-अलग और कक्षा स्तर पर विशिष्ट बनाना चाहते हैं, तो आपको निम्नलिखित के रूप में कोड लिखना होगा:

@Table(
        name = "product_serial_group_mask",
        uniqueConstraints = {
                @UniqueConstraint(columnNames = "mask"),
                @UniqueConstraint(columnNames = "group")
        }
)

इसका प्रभाव पहले कोड ब्लॉक के समान है।


एक बार जब अद्वितीय बाधा बन जाती है तो क्या मैं अपने जेपीए रिपोजिटरी में नाम के आधार पर बाधा का संदर्भ दे सकता हूं?
jDub9

@ jDub9 आप किसी इंडेक्स को क्वेरी नहीं कर सकते। आप एक क्वेरी में मुखौटा और समूह कॉलम को क्वेरी कर सकते हैं, और यह तेज प्रसंस्करण के लिए उस इंडेक्स का उपयोग करेगा (यदि आप भाग्यशाली हैं), लेकिन आप केवल एक इंडेक्स को क्वेरी नहीं कर सकते।
Dalibor Filus

उस स्तंभ का नाम डेटाबेस में वास्तविक नाम होना चाहिए। यह होना चाहिए mask_idऔर group_idयदि आप डिफ़ॉल्ट नामकरण रणनीति का उपयोग करते हैं।
विट्रो

27

जावा ईई प्रलेखन से:

public abstract boolean unique

(वैकल्पिक) क्या संपत्ति एक अद्वितीय कुंजी है। यह तालिका स्तर पर UniqueConstraint एनोटेशन के लिए एक शॉर्टकट है और इसके लिए उपयोगी है जब विशिष्ट कुंजी बाधा केवल एक फ़ील्ड है। यह बाधा प्राथमिक कुंजी मानचित्रण द्वारा दर्ज की गई किसी भी बाधा और तालिका स्तर पर निर्दिष्ट बाधाओं के अलावा लागू होती है।

डॉक देखें


इसलिए जब मैं इस कोड का उपयोग करता हूं: @ कॉलम (अद्वितीय = सत्य) @ManyToOne (वैकल्पिक = गलत, भ्रूण = FetchType.EAGER) निजी ProductSerialMask मास्क; @ कॉलम (अद्वितीय = सत्य) @ManyToOne (वैकल्पिक = गलत, भ्रूण = FetchType.EAGER) निजी समूह समूह; मेरे पास दो इंडेक्स हैं लेकिन जब दूसरे तरीके का उपयोग करते हैं तो मेरे पास एक इंडेक्स होता है जो दो कॉलम का संयोजन होता है?
नविद_घ

22

बोअज़ के जवाब के अलावा ...।

@UniqueConstraintआपको बाधा का नाम देने की अनुमति देता है , जबकि @Column(unique = true)एक यादृच्छिक नाम (जैसे UK_3u5h7y36qqa13y3mauc5xxayq) उत्पन्न करता है ।

कभी-कभी यह जानना उपयोगी हो सकता है कि एक बाधा किस तालिका से जुड़ी है। उदाहरण के लिए:

@Table(
   name = "product_serial_group_mask", 
   uniqueConstraints = {
      @UniqueConstraint(
          columnNames = {"mask", "group"},
          name="uk_product_serial_group_mask"
      )
   }
)

5

@ Boaz's और @ vegemite4me के जवाबों के अलावा ...।

लागू करने से ImplicitNamingStrategyआप बाधाओं के नामकरण के लिए नियम बना सकते हैं। ध्यान दें कि आप metadataBuilderहाइबरनेट के प्रारंभ के दौरान अपनी नामकरण रणनीति को जोड़ते हैं :

metadataBuilder.applyImplicitNamingStrategy(new MyImplicitNamingStrategy());

यह काम करता है @UniqueConstraint, लेकिन इसके लिए नहीं @Column(unique = true), जो हमेशा एक यादृच्छिक नाम (जैसे UK_3u5h7y36qqa13y3mauc5xxayq) उत्पन्न करता है।

इस समस्या को हल करने के लिए एक बग रिपोर्ट है, इसलिए यदि आप कर सकते हैं, तो कृपया इसे लागू करने के लिए वोट करें। यहाँ: https://hibernate.atlassian.net/browse/HHH-11586

धन्यवाद।

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