2012-07-03 23 views
5

है इसलिए मेरे पास एक उपयोगकर्ता तालिका, प्रोजेक्ट टेबल और उपयोगकर्ता_रोल्स तालिका है। मेरे पास एक उपयोगकर्ता है जो 2 परियोजनाओं से जुड़ा हुआ है, लेकिन जब मेरे पास सिर्फ एक ही भूमिका है तो यह उन 2 परियोजनाओं को वापस लाती है, लेकिन अगर मेरे पास 2 भूमिकाएं हैं तो यह 4 भूमिकाएं (2x2 परियोजनाएं) लौटाती है। मैं कैसे रोकूं इसहाइबरनेट डुप्लिकेट देता है क्योंकि दूसरी तालिका में डुप्लिकेट मान

यह है उपयोगकर्ता वर्ग में उपयोगकर्ता के लिए परियोजनाओं की सूची लौटने

@Override 
public List<Project> retrieve(User user) { 
    Criteria criteria = super.createCriteria(); 
    criteria.addOrder(Order.desc("date")); 
    criteria.createCriteria("users").add(Restrictions.eq("id", user.getId())); 

    return (List<Project>) criteria.list(); 
} 

मैपिंग के लिए मेरे कोड

@ManyToMany(cascade = CascadeType.ALL) 
@JoinTable(name = "Users_Projects", 
      joinColumns = @JoinColumn(name = "UserID"), inverseJoinColumns = @JoinColumn(name = "ProjectID")) 
public List<Project> getProjects() { 
    return projects; 
} 

@ElementCollection(fetch = FetchType.EAGER) 
@Enumerated(EnumType.STRING) 
@Column(name = "RoleType") 
@JoinTable(name = "User_Roles", joinColumns = @JoinColumn(name = "UserID")) 
public Set<Role> getRoles() { 
    return roles; 
} 

कोई सुझाव है कि समस्या क्या यहाँ है?

tnx

उत्तर

13

क्लासिक मापदंड क्वेरी से डुप्लीकेट पंक्तियों के मुद्दों, जो की संभावना के रूप में लंबे काम करेंगे के रूप में आप पृष्ठांकन के साथ गठबंधन करने के लिए कोशिश नहीं कर रहे के लिए "ठीक", जोड़ने के लिए है

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 

मुझे विश्वास है कि उपयोगकर्ता की भूमिकाओं की उत्सुक लोडिंग की वजह से यह आपकी स्थिति में हो रहा है। आलसी होने के लिए यह बदलना भी काम कर सकता है, और यदि आपको पेजिनेशन की आवश्यकता है तो काम करना जारी रखें।

fetch = FetchType.EAGER सेट करना हाइबरनेटेट करता है कि जब भी आप किसी उपयोगकर्ता को पुनर्प्राप्त करते हैं तो उपयोगकर्ता के लिए सभी भूमिकाओं को हमेशा लोड करना चाहते हैं, जो इसे हमेशा भूमिका तालिका में शामिल करके पूरा करता है।

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

बहुत अधिक दुर्भाग्य से, आप सरल हाइबरनेट मापदंड के साथ सबसे अधिक प्राकृतिक तरीके में पेजिंग उपयोग करने के लिए, criteria.setFirstResult और criteria.setMaxResults का उपयोग कर चाहते हैं, तो कोई बात बिगड़ क्रम में हो, तो इन प्रश्नों परिणाम ट्रांसफार्मर की जरूरत है कि से बचने के लिए डुप्लिकेट सिर्फ डॉन ' टी पेज सही है।

सभी हाइबरनेट एसक्यूएल पीढ़ी को थोड़ा बेहतर समझने के लिए, मैं this answer में वर्णित जेनरेटेड एसक्यूएल के लॉगिंग को चालू करने की सलाह दूंगा, जो कि अन्य एसओ हाइबरनेट प्रश्न में है।

+1

धन्यवाद! एक आकर्षण की तरह काम किया, क्या आप हालांकि समझा सकते हैं कि भूमिकाओं को लोड करने का कारण क्यों होगा। मुझे यह भी यकीन है कि यह मामला है, लेकिन मैं सिर्फ यह नहीं मानता कि ऐसा कुछ क्यों सेट करेगा जो उपयोगकर्ताओं के कनेक्शन का हिस्सा नहीं है-परियोजनाएं इसका कारण बनती हैं। कोई विचार? –

+0

अपनी टिप्पणी में प्रश्न पर थोड़ा और अपडेट के लिए मेरा अपडेट देखें। –