2009-07-07 9 views
35

मैं एक वर्ग SynonymMapping कहा जाता है जो एक CollectionOfElementsहाइबरनेट CollectionOfElements उत्सुक लाने डुप्लिकेट तत्वों

@Entity(name = "synonymmapping") 
public class SynonymMapping { 

    @Id private String keyId; 

    //@CollectionOfElements(fetch = FetchType.EAGER) 
    @CollectionOfElements 
    @JoinTable(name="synonymmappingvalues", joinColumns={@JoinColumn(name="keyId")}) 
    @Column(name="value", nullable=false) 
    @Sort(type=SortType.NATURAL) 
    private SortedSet<String> values; 

    public SynonymMapping() { 
     values = new TreeSet<String>(); 
    } 

    public SynonymMapping(String key, SortedSet<String> values) { 
     this(); 
     this.keyId = key; 
     this.values = values; 
    } 

    public String getKeyId() { 
     return keyId; 
    } 

    public Set<String> getValues() { 
     return values; 
    } 
} 

मैं एक परीक्षण है जहाँ मैं डेटाबेस के लिए दो SynonymMapping वस्तुओं की दुकान और फिर डेटाबेस पूछने के रूप में मैप किया मूल्यों का संग्रह है है सभी सहेजे गए समानार्थी मैपिंग ऑब्जेक्ट्स को वापस करने के लिए, मैंने संग्रहीत दो ऑब्जेक्ट्स प्राप्त करने की अपेक्षा की।

जब मैं मूल्यों के मैपिंग को उत्सुक होने के लिए बदलता हूं (जैसा कि टिप्पणी लाइन द्वारा कोड में दिखाया गया है) और परीक्षण फिर से चलाएं, मुझे चार मैचों मिलते हैं।

मैंने रनों के बीच डेटाबेस को साफ़ कर दिया है और मैं इस समस्या को उत्सुक और आलसी के बीच स्वैप कर सकता हूं।

मुझे लगता है कि इसे उन जोड़ों के साथ करना है जो हाइबरनेट बनाता है लेकिन मुझे ऑनलाइन एक निश्चित उत्तर नहीं मिल रहा है।

क्या कोई मुझे बता सकता है कि क्यों उत्सुक fetch वस्तुओं को डुप्लिकेट कर रहा है?

धन्यवाद।

+0

अपवाद के साथ प्रत्येक व्यक्ति "दिए गए पहचानकर्ता के साथ एक से अधिक पंक्ति मिली" इस बारे में जानना चाहिए। यह वास्तव में घंटों के बहुत से बचाता है यह नहीं जानता कि क्या गलत हो रहा है। @ User176668 उत्तर देखें !! –

उत्तर

27

मैपिंग में उत्सुक लाने के लिए आम तौर पर एक अच्छा विचार नहीं है - उचित प्रश्नों में उत्सुक जुड़ने के लिए बेहतर है (जब तक कि आप 100% सुनिश्चित न हों कि किसी भी और सभी परिस्थितियों में आपकी वस्तु समझ में नहीं आती/हो उस संग्रह के बिना वैध पॉप्युलेट किया जा रहा है)।

डुप्लिकेट प्राप्त करने का कारण यह है कि हाइबरनेट आंतरिक रूप से आपकी जड़ और संग्रह तालिकाओं में शामिल हो जाता है। ध्यान दें कि वे वास्तव में डुप्लीकेट हैं, उदा। 3 पर्याय तत्वों के साथ 2 समानार्थी मैपिंग के लिए आपको 6 परिणाम (2x3), प्रत्येक समानार्थी मैपिंग इकाई की 3 प्रतियां मिलेंगी। तो सबसे आसान कामकाज एक सेट में परिणामों को लपेटना है जिससे यह सुनिश्चित हो सके कि वे अद्वितीय हैं।

+34

लेकिन क्यों हाइबरनेट इन्हें फ़िल्टर नहीं कर सकता है, मैं नहीं देख सकता कि आप इसे ऐसा क्यों चाहते हैं। –

+0

मैं पुष्टि कर सकता हूं कि यह काम करता है। मैं सामान्य रूप से संग्रह का उपयोग कर रहा था, और यह एक गलती थी। –

2

रूप

SELECT DISTINCT synonym FROM SynonymMapping synonym LEFT JOIN FETCH synonym.values 

DISTINCT खंड इस प्रकार आप एक का चयन करें DISTINCT (हाइबरनेट क्वेरी लैंग्वेज) खंड इस्तेमाल कर सकते हैं हाइबरनेट में डुप्लिकेट संदर्भ निकाल देता है।

हालांकि दोनों घटक और मूल्य-प्रकार संग्रह में जीवन शैली अपने स्वामित्व वाली इकाई वर्ग से जुड़ी हुई है, तो आपको उन्हें पुनर्प्राप्त करने के लिए उन्हें चयनित खंड में घोषित करना चाहिए। (बाएं synonym.values ​​FETCH में शामिल होने)

ChssPly76 का जवाब एक और दृष्टिकोण है, लेकिन ओवरराइड भूल नहीं करता है के बराबर होती है और hashCode अनुसार विधि सेट करने के लिए अर्थ

संबंध है,

+3

मैं इस बारे में और सोच रहा था कि ऐसा क्यों होता है और क्यों हाइबरनेट के लिए डिज़ाइन निर्णय लिया गया था ताकि इस तरह के जवाब देने के विभिन्न तरीकों से इसका उत्तर दिया जा सके। – Rachel

62

मैं एक ही समस्या में कदम रखा है - जब आप @CollectionOfElements के लिए FetchType.EAGER सेट करें, हाइबरनेट एक शॉट में सबकुछ प्राप्त करने का प्रयास करता है, यानी "मास्टर" ऑब्जेक्ट से जुड़े तत्व के प्रत्येक प्रविष्टि के लिए एक एकल क्वेरी का उपयोग करना। यदि आप अपने संग्रह में @Fetch (FetchMode.SELECT) एनोटेशन जोड़ते हैं, तो इस समस्या को एन + 1 क्वेरी की लागत पर सफलतापूर्वक हल किया जा सकता है। मेरे मामले में मैं अपने मेटाडेटा आइटम (वीडियो कोडेक, ऑडियो कोडेक, आकार इत्यादि) के संग्रह के साथ MediaObject इकाई चाहता था।

 

@CollectionOfElements (targetElement = String.class, fetch = FetchType.EAGER) 
@JoinTable(name = "mo_metadata_item", joinColumns = @JoinColumn(name = "media_object_id")) 
@MapKey(columns = @Column(name = "name")) 
@Column (name = "value") 
@Fetch (FetchMode.SELECT) 
private Map<String, String> metadataItems = new HashMap<String, String>(); 
+2

इसके लिए आपको बहुत कुछ धन्यवाद। – AHungerArtist

+1

मुझे समाधान पसंद आया, क्योंकि हमें विशिष्टता प्राप्त करने के लिए परिणाम को सेट के साथ लपेटने की आवश्यकता नहीं है। – sanbhat

+0

इस के लिए बहुत धन्यवाद SOOOOO !!! मेरा दिन बचाया :) – pasql

5

मैं इस समस्या का सामना करना पड़ा है और मैं

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

का उपयोग कर यह डुप्लिकेट है जिसके द्वारा करने के लिए बनाया शामिल होने के कारण कर रहे हैं बाहर साफ करता है इसे हल: एक metadataItems संग्रह के लिए मानचित्रण के रूप में निम्नानुसार लग रहा है बाल टेबल

0

FetchMode.SELECT के बजाय एन + 1 प्रश्नों के साथ यह BatchSize ई.क्यू का उपयोग कर बेहतर है। @BatchSize(size = 200)

DISTINCT और Criteria.DISTINCT_ROOT_ENTITY मदद नहीं करता है, अगर आपको 1 से अधिक एसोसिएशन प्राप्त करना है। इस मामले के लिए अन्य समाधान देखें: https://stackoverflow.com/a/46013654/548473

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