2012-10-27 18 views
15

कहें कि मेरे पास दो इकाइयां उपयोगकर्ता और अधिसूचना है। और मेरे पास एक रिश्ता है जैसा कि नीचे दिखाया गया है।जेपीए वनटॉनी: सूची बनाम सेट

public class UserAccount{ 

    @Id 
    @Column(name = "USER_NAME") 
    private String emailid; 

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    @JoinTable(name = "USERS_NOTIFICATIONS", joinColumns = { @JoinColumn(name = "USER_NAME") }, inverseJoinColumns = { @JoinColumn(name = "NOTIFICATION_ID") }) 
    private List<Notification> notifications; 

    //setters, getter, equals and hashcode 
} 

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

Hibernate: delete from USERS_NOTIFICATIONS where USER_NAME=? 
Hibernate: insert into USERS_NOTIFICATIONS (USER_NAME, NOTIFICATION_ID) values (?, ?) 
Hibernate: insert into USERS_NOTIFICATIONS (USER_NAME, NOTIFICATION_ID) values (?, ?) 
Hibernate: insert into USERS_NOTIFICATIONS (USER_NAME, NOTIFICATION_ID) values (?, ?) 
//as many inserts as the notifications the user has 

समान उपयोगकर्ता प्रत्येक उपयोगकर्ता के साथ होता है। अब, यदि मैं सूची के साथ सूची को प्रतिस्थापित करता हूं, तो सामान्य प्रविष्टि होती है। और मुझे doucmentation और blog पढ़ने के बाद कारण मिला। डॉक्स

  • एक यूनिडायरेक्शनल OneToMany संघ सेट में से

    टिप्पणियों पसंद किया जाता है।

यह स्पष्ट किया जाना चाहिए कि अनुक्रमित संग्रह और सेट जोड़कर, निकालकर और तत्वों को अद्यतन करने की दृष्टि से सबसे कुशल संचालन की अनुमति है।

  • द्विदिश OneToMany रिश्ते में (ManyToOne प्रबंध) सूची और बैग कुशल हैं।

बैग और सूचियों सबसे कारगर उलटा संग्रह हैं

सवालों का युगल

  1. क्या इसका मतलब मैं एक यूनिडायरेक्शनल OneToMany मानचित्रण में एक सूची पर एक सेट पसंद करते हैं करने के लिए है (हालांकि काफी स्पष्ट)? लेकिन क्या वहां कोई काम है?
  2. या क्या मुझे एक सूची का उपयोग करने के लिए एक द्विपक्षीय संबंध बनाने के लिए अपने डोमेन को ट्वीक करना है, जब मेरे पास डुप्लीकेट है।
+2

से स्वतंत्र होने के लिए छोड़ दिया, किसी ने सोचा होगा कि जब आप ऑर्डर करना चाहते हैं तो आप एक सूची का उपयोग करते हैं, और सेट करते समय सेट का उपयोग करते हैं; मॉडलिंग के लिए आवश्यक चीज़ों के आधार पर अपना मॉडल चुनें ... किसी भी दृढ़ता समाधान के बावजूद। किसी भी दृढ़ता समाधान को – DataNucleus

+3

@ डेटानाक्लियस को संभालने में सक्षम होना चाहिए: किसी ने सोचा होगा। एक ने यह भी सोचा होगा कि हाइबरनेट एक यूनिडायरेक्शनल मानचित्र को कुशलतापूर्वक जोड़ने में संभाल लेगा। कभी-कभी पता चलता है कि विचारों को गुमराह किया गया था! –

+0

@ डेटाटाइक्लियस: यहां तक ​​कि मैंने सोचा कि यह वही तरीका था, लेकिन मैंने ऊपर वर्णित समस्या को प्राप्त करने के बाद और प्रलेखन के माध्यम से जाने के बाद मुझे पाया कि इससे कुछ और है। – shazinltc

उत्तर

1

सूची: इसमें डुप्लिकेट तत्वों की अनुमति देता है।

सेट: सभी तत्व अद्वितीय होना चाहिए।

अब, हटाया जा सकता है क्योंकि आप सूची में अधिक लेखन तत्व हैं, और इसलिए जब आप UserAccount प्रकार की निरंतर इकाई को संशोधित करते हैं, तो यह उस इकाई को हटा रहा है जो पहले सूची में है।

+0

नहीं .. यह मामला नहीं है। कृपया सूचीबद्ध दस्तावेज पढ़ें। इसे हटाने का कारण है। – shazinltc

8

मुझे इस समस्या का सामना बहुत समय पहले नहीं हुआ था ...संक्षेप में हाइबरनेट https://fedcsis.org/proceedings/2013/pliks/322.pdf

में कई एसोसिएशन के लिए एक के प्रदर्शन Antipatterns:

मैं इस लेख पाया

  • थैला अर्थ विज्ञान ->List/Collection + @OneToMany -> एक तत्व जोड़ा गया: 1 हटाना , एन सम्मिलित करें, एक तत्व हटाया गया: 1 हटाएं, एन सम्मिलित करें
  • सूची अर्थशास्त्र ->List + @OneToMany + @IndexColumn/@OrderColumn -> एक तत्व जोड़ा गया: 1 डालने, एम अद्यतन, एक तत्व निकाल दिया गया: 1 हटाने के लिए, एम अपडेट
  • सेट अर्थ विज्ञान ->Set + @OneToMany -> एक तत्व जोड़ा गया: 1 सम्मिलित करें, एक तत्व निकाल दिया गया: 1 हटाना

मेरे लिए: हाँ इसका मतलब है कि आपको अपने List से Set को unidirectional @OneToMany के लिए बदलना होगा। इसलिए मैं अपने मॉडल हाइबरनेट उम्मीदों के साथ मैच के लिए और कहा कि मुद्दों का एक बहुत का कारण है क्योंकि आवेदन के मद्देनजर हिस्सा List ज्यादातर पर भरोसा था ...

बदल एक हाथ में Set देखते हैं क्योंकि मेरे लिए एक तार्किक पसंद है दूसरी तरफ, कोई डुप्लिकेशंस List से निपटना आसान था।

तो जेपीए/हाइबरनेट ने मुझे मॉडल ऑब्जेक्ट को बदलने के लिए मजबूर किया और यह पहली बार नहीं था, जब आप @EmbededId का उपयोग कर रहे हैं तो आप ऐसा कुछ करते हैं जो आप शायद जेपीए/हाइबरनेट के बिना ऐसा नहीं करेंगे। और जब आपको सभी अनुप्रयोगों में HibernateProxy से अवगत होना चाहिए, विशेष रूप से समान तरीके से ... else if(object instanceof HibernateProxy) { ..., आप देखते हैं कि जेपीए/हाइबरनेट पर्सिटेंस परत अन्य परतों में थोड़ा सा घुसपैठ कर रही है।

लेकिन जब मैं प्रत्यक्ष रूप से जेडीबीसी का उपयोग करता हूं तो मैं दृढ़ता की सुविधा के लिए मॉडल या buisness विधियों को बदलने के लिए भी उपयोग करता हूं ... परत अलगाव एक सपना या लागत 100% पर बहुत अधिक हो सकती है?

और आप एक Set आदेश कर सकते हैं अगर वे एनोटेशन @OrderBy

यह एक समस्या है जब कुछ कोड List पर भरोसा करते हैं और (जैसे JSF/PrimeFaces <dataTable> या <repeat> घटक के रूप में) बदला नहीं जा सकता लाने के साथ TreeSet तरह SortedSet हैं तो आप अपने List में Set बदल सकते हैं और Set के लिए वापस जाने के लिए है, लेकिन यदि आप setNotifications(new HashSet<>(notificationList)) कर आप अतिरिक्त प्रश्न हैं जाएगा, क्योंकि सेट एक org.hibernate.collection.PersistentSet हाइबरनेट द्वारा प्रबंधित है ... तो मैं addAll() और removeAll() इस्तेमाल किया में setters के जगह:

protected <E> void updateCollection(@NonNull Collection<E> oldCollection, @NonNull Collection<E> newCollection) { 
    Collection<E> toAdd = new ArrayList<>(newCollection) ; 
    toAdd.removeAll(oldCollection) ; 

    Collection<E> toRemove = new ArrayList<>(oldCollection) ; 
    toRemove.removeAll(newCollection) ; 

    oldCollection.removeAll(toRemove) ; 
    oldCollection.addAll(toAdd) ; 
} 

मन अपने @Entity की equals() और hashCode() तरीकों ...

एक और समस्या यह है कि आपको जेपीए और हाइबरनेट दोनों को मास्टर करने की आवश्यकता है यदि आप जेबरा को हाइबरनेट के साथ कार्यान्वयन के रूप में उपयोग करना चाहते हैं क्योंकि सेट/सूची/बैग अर्थशास्त्री जेबरा से नहीं है (सही है अगर मैं गलत हूं)

कार्यान्वयन को सारणीबद्ध करने के लिए एक विनिर्देशन एक विशिष्ट विक्रेता पर निर्भर नहीं है। यद्यपि अधिकांश जावाईई चश्मा सफल हुए, जेपीए मेरे लिए असफल रहा और मैंने हाइबरनेट

+0

धन्यवाद! पेपर वास्तव में और भी खराब पढ़ रहा है! –

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