2009-09-23 7 views
5

मेरी इकाइयों में से एक के लिए यहां एक समग्र प्राथमिक कुंजी है।@IdClass जेपीए एनोटेशन

public class GroupMembershipPK implements Serializable{ 

    private static final long serialVersionUID = 7816433876820743311L; 

    private User user; 
    private Group group; 

    public GroupMembershipPK(){ 
    } 

    public boolean equals(Object o){ 
     if(o==null){ 
      return false; 
     } 

     if(o instanceof GroupMembershipPK){ 
      final GroupMembershipPK groupMembershipPK=(GroupMembershipPK)o; 
      return groupMembershipPK.group.getGroupName().equals(this.group.getGroupName()) && 
       groupMembershipPK.user.getName().equals(this.user.getName()); 
     } 
     return false; 
    } 

    public int hashCode(){ 
     return super.hashCode(); 
    } 
} 

उपरोक्त का उपयोग एक समग्र प्राथमिक कुंजी के रूप में मेरी इकाई (भाग का) है।

@Entity 
@IdClass(GroupMembershipPK.class) 
public class GroupMembership extends AbstractModelElementVersionOther{ 

    private static final long serialVersionUID = 9188465566607060376L; 

    private String memType; 
    private Group group; 
    private User user; 

    public GroupMembership(){ 
     super(); 
    } 

    @Column(nullable=false) 
    public String getMemType(){ 
     return this.memType; 
    } 

    public void setMemType(String memType){ 
     this.memType=memType; 
    } 

    @Id 
    @ManyToOne 
    @JoinColumn(name="groupId") 
    public Group getGroup(){ 
     return this.group; 
    } 

    public void setGroup(Group group){ 
     this.group=group; 
    } 

    @Id 
    @ManyToOne 
    @JoinColumn(name="userId") 
    public User getUser(){ 
     return this.user; 
    } 

    public void setUser(User user){ 
     this.user=user; 
    } 

    @Override 
    public boolean equals(Object o) { 
// 

मैं एक छोटे से क्या ऊपर इकाई के लिए बराबर विधि कार्यान्वयन होना चाहिए पर उलझन में हूँ। मैं दो समग्र प्राथमिक कुंजी की तुलना कैसे कर सकता हूं?

मेरे कोड के अन्य भागों पर कोई भी टिप्पणी भी स्वागत है।

उत्तर

7

यह एक अच्छा विचार नहीं है कि आप इकाइयों को प्राथमिक कुंजी के रूप में स्टोर करते हैं। क्वेरी भाषा और जेपीए 1.0 का उपयोग करते समय कुछ सीमाएं समर्थित नहीं हैं। इसके अलावा प्राथमिक कुंजी के रूप में इकाइयों का उपयोग करने की आवश्यकता नहीं है। सोचो के बारे में आप इसे चाहते हैं, निम्नलिखित प्रश्न

A class that behaves like @Entity and @Embeddable

Answer one

Comment about answer one

आप एक इकाई का उपयोग कर के रूप में प्राथमिक कुंजी आवश्यक नहीं है देखेंगे में आयोजित एक विशेष नज़र रखना।

public class GroupMembershipPK implements Serializable { 

    private User user; 
    private Group group; 

} 

के बजाय

उपयोग

public class GroupMembershipPK implements Serializable { 

    private Integer userId; 
    private Integer groupId; 

} 

के बराबर होती है कार्यान्वयन महत्वपूर्ण है क्योंकि जेपीए यह का उपयोग करके दो संस्थाओं तुलना (एक इकाई कार्यान्वयन के बराबर होती है का उपयोग करके हठ संदर्भ में है जेपीए जाँच करता है कि)। तो अगर आप को

public boolean equals(Object o) { 
    if(o == null) 
     return false; 

    if(!(o instanceof GroupMembershipPK)) 
     return false; 

    GroupMembershipPK other = (GroupMembershipPK) o; 
    if(!(getUserId().equals(other.getUserId())) 
     return false; 

    if(!(getGroupId().equals(other.getGroupId())) 
     return false; 

    return true; 
} 

सलाह अनुसार लागू कर सकते हैं: यह एक अच्छा विचार है, क्योंकि कुछ समय पर, जेपीए कार्यान्वयन प्रदर्शन के मुद्दों की वजह से एक प्रॉक्सी वस्तु का उपयोग करता है आप क्षेत्र का उपयोग संपत्ति का उपयोग करने के बजाय का उपयोग करें। प्रॉक्सी ऑब्जेक्ट संपत्ति पहुंच का उपयोग करता है क्योंकि यह आवश्यक होने पर जेपीए कार्यान्वयन डेटाबेस को हिट करने की अनुमति देता है।

एक समग्र प्राथमिक कुंजी का उपयोग करने वाली ऑब्जेक्ट को कैसे सहेजना है?

User user = new user(); 
Group group = new Group(); 

entityManager.save(user); 
entityManager.save(group); 

entityManager.flush(); 

UserGroup userGroup = new UserGroup(); 

userGroup.setId(new UserGroup.UserGroupId(user.getId(), group.getId())); 

entityManager.save(userGroup); 

क्या आप जानना चाहते हैं कि उपयोगकर्ता समूह को कैसे कार्यान्वित किया जाए?

public class UserGroup { 

    private UserGroupId id; 

    // You can create UserGroupId outside UserGroup class 
    // Feel free to choice your best approach 
    @Embeddable 
    public static class UserGroupId implements Serializable { 

     private Integer userId; 
     private Integer groupId; 

     // required no-arg constructor 
     public UserGroupId() {} 

     public UserGroupId(Integer userId, Integer groupId) { 
      this.userId = userId; 
      this.roupId = groupId; 
     } 

     // getter's and setter's 

     // equals and hashcode as shown above 

    } 

    @EmbeddedId 
    public UserGroupId getId() { 
     return this.id; 
    } 

    public setId(UserGroupId id) { 
     this.id = id; 
    } 
} 

समग्र प्राथमिक कुंजी का उपयोग करने के लिए एक अन्य दृष्टिकोण आईडीक्लास है। देखें IdClass

संबंध है,

+0

तुम भी, userId और ग्रुप गुण का उपयोग करता है के बाद से बराबर वस्तुओं भी एक ही हैश होना आवश्यक है एक hashCode विधि को लागू करना चाहिए। उदाहरण के लिए: (getUserId() == शून्य? 0: getUserId()। हैशकोड())^(getGroupId() == null? 0: getGroupId()। हैशकोड()) –

+0

@ जोर्न होर्स्टमान हाय, आप हैं सही। लेकिन इसे लागू किया गया है केवल उत्तर के कारण कार्यान्वयन बराबर है। वैसे भी धन्यवाद –

+0

@ आर्थर रोनाल्ड। धन्यवाद, पूरी तरह से काम करता है। हालांकि, क्या आप मुझे बता सकते हैं कि उपर्युक्त वर्णित समग्र प्राथमिक कुंजी का उपयोग करके इकाई को कैसे बनाए रखना है? जब मैं ऐसा करने का प्रयास करता हूं तो मुझे जेबॉस में निम्न त्रुटि मिलती है .------- "थ्रेड में अपवाद" मुख्य "javax.ejb.EJBException: javax.persistence.PersistenceException: org.hibernate.id.IdentifierGenerationException: के लिए आईडी सहेजने से पहले इस वर्ग को मैन्युअल रूप से असाइन किया जाना चाहिए() " – soontobeared

1

यह आंशिक रूप से उल्लेख किया गया था, वैसे भी:

  1. जब equals विधि को लागू करने के लिए, आप उपयोग instanceof उपवर्गों के साथ तुलना अनुमति देने के लिए करना चाहिए। यदि हाइबरनेट आलसी एक से एक या एक से कई संबंधों को लोड करता है, तो आपके पास सादे वर्ग की जगह कक्षा के लिए प्रॉक्सी होगी। एक प्रॉक्सी एक उपclass है। कक्षा के नामों की तुलना विफल हो जाएगी।
    अधिक तकनीकी रूप से, आपको Liskovs Substitution Principle का पालन करना चाहिए और समरूपता को अनदेखा करना चाहिए।
  2. अगला pitfall name.equals(that.getName()) के बजाय name.equals(that.name) जैसे कुछ का उपयोग कर रहा है। पहला असफल हो जाएगा, अगर वह प्रॉक्सी है।

http://www.laliluna.de/jpa-hibernate-guide/ch06s06.html

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