यह प्रश्न कुछ हद तक हाइबरनेट एनोटेशन प्लेसमेंट प्रश्न से संबंधित है ।
लेकिन मैं जानना चाहता हूं कि कौन सा बेहतर है ? गुणों के माध्यम से या खेतों के माध्यम से पहुंच? हर एक के फायदे और नुकसान क्या हैं?
यह प्रश्न कुछ हद तक हाइबरनेट एनोटेशन प्लेसमेंट प्रश्न से संबंधित है ।
लेकिन मैं जानना चाहता हूं कि कौन सा बेहतर है ? गुणों के माध्यम से या खेतों के माध्यम से पहुंच? हर एक के फायदे और नुकसान क्या हैं?
जवाबों:
मुझे एक्सेसर्स पसंद हैं, क्योंकि मुझे जब भी ज़रूरत होती है मैं अपने एक्सेसर्स में कुछ व्यावसायिक तर्क जोड़ सकता हूं। यहाँ एक उदाहरण है:
@Entity
public class Person {
@Column("nickName")
public String getNickName(){
if(this.name != null) return generateFunnyNick(this.name);
else return "John Doe";
}
}
इसके अलावा, यदि आप मिक्स में एक और परिवाद फेंकते हैं (जैसे कुछ JSON-कन्वर्टिंग लिब या BeanMapper या डोजर या अन्य बीन मैपिंग / क्लंटर लीवर जो गटर / सेटर प्रॉपर्टी के आधार पर होता है) तो आपको यह गारंटी होगी कि परिवाद दृढ़ता के साथ सिंक में है प्रबंधक (दोनों गेट्टर / सेटर का उपयोग करते हैं)।
दोनों के लिए तर्क हैं, लेकिन उनमें से अधिकांश कुछ उपयोगकर्ता की आवश्यकताओं से स्टेम करते हैं "क्या होगा यदि आपको तर्क जोड़ने की आवश्यकता है", या "xxxx इनकैप्सुलेशन को तोड़ता है"। हालांकि, किसी ने वास्तव में सिद्धांत पर टिप्पणी नहीं की है, और एक उचित तर्क दिया है।
हाइबरनेट / जेपीए वास्तव में क्या कर रहा है जब यह एक वस्तु को बनाए रखता है - अच्छी तरह से, यह वस्तु की स्थिति को बनाए रखता है। इसका मतलब है कि इसे इस तरह से संग्रहीत करना कि इसे आसानी से पुन: पेश किया जा सके।
एनकैप्सुलेशन क्या है? एनकैप्सुलेशन का अर्थ है कि डेटा (या राज्य) को एक इंटरफेस के साथ इनकैप्सुलेट करना जो एप्लिकेशन / क्लाइंट डेटा को सुरक्षित रूप से एक्सेस करने के लिए उपयोग कर सकते हैं - इसे लगातार और वैध रखते हुए।
इसे MS Word की तरह समझें। एमएस वर्ड मेमोरी में दस्तावेज़ का एक मॉडल रखता है - दस्तावेज़ स्टेट। यह एक इंटरफ़ेस प्रस्तुत करता है जिसे उपयोगकर्ता दस्तावेज़ को संशोधित करने के लिए उपयोग कर सकता है - बटन, उपकरण, कीबोर्ड कमांड आदि का एक सेट। हालांकि, जब आप उस दस्तावेज़ को जारी रखना (सहेजना) चुनते हैं, तो यह आंतरिक स्थिति को बचाता है, न कि कीप्स का सेट और इसे उत्पन्न करने के लिए माउस क्लिक का उपयोग किया जाता है।
ऑब्जेक्ट की आंतरिक स्थिति को सहेजना, एनकैप्सुलेशन को नहीं तोड़ता है - अन्यथा आप वास्तव में समझ नहीं पाते हैं कि एनकैप्सुलेशन का अर्थ क्या है, और यह क्यों मौजूद है। यह वास्तव में वस्तु क्रमांकन जैसा है।
इस कारण से, अधिकांश मामलों में, यह FIELDS को बनाए रखने के लिए उपयुक्त है, न कि ACCESSORS के। इसका मतलब है कि किसी ऑब्जेक्ट को डेटाबेस से ठीक उसी तरह से फिर से बनाया जा सकता है जिस तरह से संग्रहीत किया गया था। इसे किसी भी सत्यापन की आवश्यकता नहीं है, क्योंकि यह मूल पर किया गया था जब इसे बनाया गया था, और इससे पहले कि यह डेटाबेस में संग्रहीत किया गया था (जब तक, भगवान न करे, आप डीबी में अमान्य डेटा संग्रहीत कर रहे हैं !!!!)। इसी तरह, मूल्यों की गणना करने की कोई आवश्यकता नहीं होनी चाहिए, क्योंकि वे पहले ही गणना की गई थीं कि ऑब्जेक्ट को संग्रहीत किया गया था। ऑब्जेक्ट को सहेजने से पहले बस उसी तरह दिखना चाहिए जैसे उसने किया था। वास्तव में, गेटर्स / सेटर में अतिरिक्त सामान जोड़कर आप वास्तव में जोखिम बढ़ा रहे हैं कि आप कुछ ऐसा बनाएंगे जो मूल की सटीक प्रतिलिपि नहीं है।
बेशक, इस कार्यक्षमता को एक कारण के लिए जोड़ा गया था। एक्सेसरों को जारी रखने के लिए कुछ वैध उपयोग के मामले हो सकते हैं, हालांकि, वे आम तौर पर दुर्लभ होंगे। एक उदाहरण यह हो सकता है कि आप एक परिकलित मान को बनाए रखने से बचना चाहते हैं, हालांकि आप यह सवाल पूछना चाहते हैं कि आप मूल्य के गेटर में मांग पर इसकी गणना क्यों नहीं करते हैं, या इसे प्राप्त करने वाले में आलस्य करते हैं। व्यक्तिगत रूप से मैं किसी भी अच्छे उपयोग के मामले के बारे में नहीं सोच सकता, और यहाँ कोई भी उत्तर वास्तव में "सॉफ्टवेयर इंजीनियरिंग" उत्तर नहीं देता है।
मैं फील्ड एक्सेस पसंद करता हूं, क्योंकि इस तरह मैं प्रत्येक संपत्ति के लिए गेटटर / सेटर प्रदान करने के लिए मजबूर नहीं हूं।
Google के माध्यम से एक त्वरित सर्वेक्षण बताता है कि फ़ील्ड एक्सेस बहुसंख्यक है (जैसे, http://java.dzone.com/tips/12-feb-jpa-20-why-accesstype )।
मेरा मानना है कि फ़ील्ड एक्सेस स्प्रिंग द्वारा अनुशंसित मुहावरा है, लेकिन मैं इसे वापस करने के लिए एक संदर्भ नहीं पा सकता हूं।
एक संबंधित SO प्रश्न है जो प्रदर्शन को मापने की कोशिश करता है और इस निष्कर्ष पर पहुंचा कि "कोई अंतर नहीं है"।
यहां ऐसी स्थिति है जहां आपको संपत्ति एक्सेसरों का उपयोग करना है। कल्पना कीजिए कि आपके पास एक सामान्य सार वर्ग है जिसमें 8 ठोस उपवर्गों में विरासत के लिए बहुत सारी कार्यान्वयन अच्छाई है:
public abstract class Foo<T extends Bar> {
T oneThing;
T anotherThing;
// getters and setters ommited for brevity
// Lots and lots of implementation regarding oneThing and anotherThing here
}
अब वास्तव में आपको इस वर्ग की व्याख्या कैसे करनी चाहिए? इसका उत्तर है कि आप इसे किसी भी क्षेत्र या संपत्ति के उपयोग के साथ नहीं बता सकते क्योंकि आप इस बिंदु पर लक्ष्य इकाई को निर्दिष्ट नहीं कर सकते। आपको ठोस कार्यान्वयन की व्याख्या करनी है। लेकिन जब से इस सुपरक्लास में लगातार संपत्तियों की घोषणा की जाती है, तो आपको उपवर्गों में संपत्ति का उपयोग करना होगा।
एब्सट्रैक्ट जेनेरिक सुपर-क्लास वाले एप्लिकेशन में फ़ील्ड एक्सेस एक विकल्प नहीं है।
abstract T getOneThing()
, और कर सकते हैं abstract void setOneThing(T thing)
।
मैं संपत्ति एक्सेसरों को प्राथमिकता देना और उनका उपयोग करना चाहता हूं:
foo.getId()
प्रॉक्सी को शुरू किए बिना कॉल करने की अनुमति देता है (हाइबरनेट का उपयोग करते समय महत्वपूर्ण, जब तक कि HHH-3718 हल न हो जाए)।दोष यह है:
@Transient
आसपास हैं।यह वास्तव में एक विशिष्ट मामले पर निर्भर करता है - दोनों विकल्प एक कारण के लिए उपलब्ध हैं। IMO इसे तीन मामलों में उबालता है:
यदि आप बस मान (जैसे एन्क्रिप्शन या गणना) निर्धारित करने की तुलना में बसों में अधिक कुछ करना चाहते हैं, तो मैं दृढ़ता से फ़ील्ड एक्सेस और गेटर्स (प्रॉपर्टी एक्सेस) पर एनोटेशन की सिफारिश नहीं करूंगा।
संपत्ति के उपयोग के साथ समस्या यह है कि बसने वाले को तब भी कहा जाता है जब ऑब्जेक्ट लोड होता है। यह मेरे लिए कई महीनों तक ठीक काम किया है जब तक हम एन्क्रिप्शन शुरू नहीं करना चाहते थे। हमारे उपयोग के मामले में हम सेटर में एक फ़ील्ड को एन्क्रिप्ट करना चाहते हैं और इसे गेटटर में डिक्रिप्ट करते हैं। प्रॉपर्टी ऐक्सेस के साथ अब समस्या यह थी कि जब हाइबरनेट ने ऑब्जेक्ट को लोड किया था तो वह फ़ील्ड को पॉप्युलेट करने के लिए सेटर को भी बुला रहा था और इस तरह एन्क्रिप्टेड वैल्यू को फिर से एन्क्रिप्ट कर रहा था। इस पोस्ट में यह भी उल्लेख किया गया है: जावा हाइबरनेट: अलग-अलग प्रॉपर्टी सेट फ़ंक्शन के व्यवहार पर निर्भर करता है कि कौन इसे कॉल कर रहा है
इससे मुझे तब तक सिरदर्द होता है जब तक कि मुझे फील्ड एक्सेस और प्रॉपर्टी एक्सेस के बीच का अंतर याद नहीं रहता। अब मैंने अपने सभी एनोटेशन को प्रॉपर्टी ऐक्सेस से फील्ड एक्सेस तक पहुंचा दिया है और यह अब ठीक काम करता है।
मैं निम्नलिखित कारणों से फ़ील्ड एक्सेस का उपयोग करना पसंद करता हूं:
संपत्ति का उपयोग कर सकते हैं जब बराबरी / hashCode लागू करने और बहुत बुरा कीड़े को जन्म दे सकता सीधे क्षेत्रों को संदर्भित (के रूप में अपने ही टिककर खेल के माध्यम से विरोध)। ऐसा इसलिए है क्योंकि गेटर्स एक्सेस होने पर प्रॉक्सी को केवल इनिशियलाइज़ किया जाता है, और डायरेक्ट-फील्ड एक्सेस बस शून्य रूप से वापस आ जाएगी।
संपत्ति का उपयोग सभी व्याख्या करने की आवश्यकता है उपयोगिता तरीकों (जैसे addChild / removeChild) के रूप में @Transient
।
फ़ील्ड एक्सेस के साथ हम एक गेट्टर को उजागर न करके @Version फ़ील्ड छिपा सकते हैं। एक गेट्टर भी एक सेटर को जोड़ने के लिए नेतृत्व कर सकता है, और version
फ़ील्ड को कभी भी मैन्युअल रूप से सेट नहीं किया जाना चाहिए (जो बहुत खराब मुद्दों को जन्म दे सकता है)। सभी संस्करण incrementation के माध्यम से शुरू किया जा चाहिए OPTIMISTIC_FORCE_INCREMENT या PESSIMISTIC_FORCE_INCREMENT स्पष्ट ताला।
version
फील्ड के लिए एक्सपोजर एक्सेस अक्सर उन स्थितियों में उपयोगी होता है, जिनमें डीटॉओ का इस्तेमाल अलग-अलग संस्थाओं के बजाय किया जाता है।
मुझे लगता है कि संपत्ति की घोषणा करना बेहतर है क्योंकि फ़ील्ड अपडेट करने से सीधे एनकैप्सुलेशन टूट जाता है, तब भी जब आपका ओआरएम ऐसा करता है।
यहाँ एक महान उदाहरण है जहाँ यह आपको जला देगा: आप शायद उसी जगह (या तो फ़ील्ड या गुण) हाइबरनेट सत्यापनकर्ता और दृढ़ता के लिए अपने एनोटेशन चाहते हैं। यदि आप अपने हाइबरनेट सत्यापनकर्ता संचालित सत्यापन का परीक्षण करना चाहते हैं, जो किसी फ़ील्ड पर एनोटेट किए गए हैं, तो आप अपनी इकाई परीक्षण को केवल सत्यापनकर्ता को अलग करने के लिए अपनी इकाई का उपयोग नहीं कर सकते। आउच।
मेरा मानना है कि प्रॉपर्टी ऐक्सेस बनाम फील्ड एक्सेस आलसी इनिशियलाइजेशन के संबंध में समान रूप से भिन्न है।
2 मूल बीन्स के लिए निम्न मैपिंग पर विचार करें:
<hibernate-mapping package="org.nkl.model" default-access="field">
<class name="FieldBean" table="FIELD_BEAN">
<id name="id">
<generator class="sequence" />
</id>
<property name="message" />
</class>
</hibernate-mapping>
<hibernate-mapping package="org.nkl.model" default-access="property">
<class name="PropBean" table="PROP_BEAN">
<id name="id">
<generator class="sequence" />
</id>
<property name="message" />
</class>
</hibernate-mapping>
और निम्नलिखित इकाई परीक्षण:
@Test
public void testFieldBean() {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
FieldBean fb = new FieldBean("field");
Long id = (Long) session.save(fb);
tx.commit();
session.close();
session = sessionFactory.openSession();
tx = session.beginTransaction();
fb = (FieldBean) session.load(FieldBean.class, id);
System.out.println(fb.getId());
tx.commit();
session.close();
}
@Test
public void testPropBean() {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
PropBean pb = new PropBean("prop");
Long id = (Long) session.save(pb);
tx.commit();
session.close();
session = sessionFactory.openSession();
tx = session.beginTransaction();
pb = (PropBean) session.load(PropBean.class, id);
System.out.println(pb.getId());
tx.commit();
session.close();
}
आप आवश्यक चयनों में सूक्ष्म अंतर देखेंगे:
Hibernate:
call next value for hibernate_sequence
Hibernate:
insert
into
FIELD_BEAN
(message, id)
values
(?, ?)
Hibernate:
select
fieldbean0_.id as id1_0_,
fieldbean0_.message as message1_0_
from
FIELD_BEAN fieldbean0_
where
fieldbean0_.id=?
0
Hibernate:
call next value for hibernate_sequence
Hibernate:
insert
into
PROP_BEAN
(message, id)
values
(?, ?)
1
यही है, कॉलिंग के fb.getId()
लिए एक चयन की आवश्यकता होती है, जबकि pb.getId()
ऐसा नहीं है।
मुझे क्षेत्र-आधारित पहुंच चुनने के लिए सबसे महत्वपूर्ण कारणों को संक्षेप में बताने की कोशिश करते हैं। यदि आप अधिक गहराई से गोता लगाना चाहते हैं, तो कृपया मेरे ब्लॉग पर इस लेख को पढ़ें: जेपीए और हाइबरनेट में पहुंच रणनीतियाँ - कौन सा बेहतर है, क्षेत्र या संपत्ति का उपयोग?
क्षेत्र-आधारित पहुंच बेहतर विकल्प है। इसके 5 कारण इस प्रकार हैं:
कारण 1: अपने कोड की बेहतर पठनीयता
यदि आप फ़ील्ड-आधारित पहुंच का उपयोग करते हैं, तो आप अपनी मैपिंग एनोटेशन के साथ अपनी इकाई विशेषताओं को एनोटेट करते हैं। अपनी कक्षा के शीर्ष पर सभी इकाई विशेषताओं की परिभाषा रखकर, आपको सभी विशेषताओं और उनके मानचित्रण का एक अपेक्षाकृत कॉम्पैक्ट दृश्य मिलता है।
कारण 2: ओट गेट्टर या सेटर विधियां जिन्हें आपके एप्लिकेशन द्वारा नहीं बुलाया जाना चाहिए
क्षेत्र-आधारित पहुंच का एक और लाभ यह है कि आपका दृढ़ता प्रदाता, जैसे, हाइबरनेट या एक्लिप्सलिंक, आपकी इकाई विशेषताओं के गेट्टर और सेटर तरीकों का उपयोग नहीं करता है। इसका मतलब है कि आपको ऐसी कोई विधि प्रदान करने की आवश्यकता नहीं है जिसका उपयोग आपके व्यवसाय कोड द्वारा नहीं किया जाना चाहिए। यह अक्सर प्राथमिक प्राथमिक विशेषताओं या संस्करण कॉलमों के सेटर तरीकों के लिए होता है । आपका दृढ़ता प्रदाता इन विशेषताओं के मूल्यों का प्रबंधन करता है, और आपको उन्हें प्रोग्रामेटिक रूप से सेट नहीं करना चाहिए।
कारण 3: गेट्टर और सेटर विधियों का लचीला कार्यान्वयन
क्योंकि आपका दृढ़ता प्रदाता गेट्टर और सेटर विधियों को कॉल नहीं करता है, वे किसी भी बाहरी आवश्यकताओं को पूरा करने के लिए मजबूर नहीं होते हैं। आप इन तरीकों को अपनी इच्छानुसार लागू कर सकते हैं। यह आपको व्यापार-विशिष्ट सत्यापन नियमों को लागू करने, अतिरिक्त व्यावसायिक तर्क को ट्रिगर करने या इकाई विशेषता को एक अलग डेटा प्रकार में परिवर्तित करने में सक्षम बनाता है।
उदाहरण के लिए, आप एक जावा में एक वैकल्पिक संघ या विशेषता को लपेटने के लिए उपयोग कर सकते हैं ।Optional
कारण 4: उपयोगिता विधियों को चिह्नित करने की आवश्यकता नहीं है @Transient
क्षेत्र-आधारित पहुंच रणनीति का एक अन्य लाभ यह है कि आपको अपनी उपयोगिता विधियों के साथ टिप्पणी करने की आवश्यकता नहीं है @Transient
। यह एनोटेशन आपके हठ प्रदाता को बताता है कि एक विधि या विशेषता इकाई की निरंतर स्थिति का हिस्सा नहीं है। और क्योंकि फील्ड-प्रकार की पहुंच के साथ लगातार स्थिति आपकी इकाई की विशेषताओं द्वारा परिभाषित हो जाती है, आपका जेपीए कार्यान्वयन आपकी इकाई के सभी तरीकों की उपेक्षा करता है।
कारण 5: परदे के पीछे से काम करते समय बग से बचें
हाइबरनेट एक-एक संघों के लिए आलसी भ्रूण के लिए परदे के पीछे का उपयोग करता है, ताकि यह इन संघों के आरंभ को नियंत्रित कर सके। यह दृष्टिकोण लगभग सभी स्थितियों में ठीक काम करता है। यदि आप संपत्ति-आधारित पहुंच का उपयोग करते हैं तो यह एक खतरनाक नुकसान का परिचय देता है।
यदि आप गुण-आधारित पहुँच का उपयोग करते हैं, तो हाइबरनेट आपको प्रॉपर ऑब्जेक्ट की विशेषताओं को प्रारंभ करता है जब आप गेट्टर विधि को कॉल करते हैं। यदि आप अपने व्यवसाय कोड में प्रॉक्सी ऑब्जेक्ट का उपयोग करते हैं तो हमेशा ऐसा ही होता है। लेकिन काफी बराबर और हैशकोड कार्यान्वयन सीधे विशेषताओं तक पहुंचते हैं। यदि यह पहली बार है जब आप किसी भी छद्म विशेषताओं का उपयोग कर रहे हैं, तो ये विशेषताएँ अभी भी असंवैधानिक हैं।
डिफ़ॉल्ट रूप से, JPA प्रदाता इकाई फ़ील्ड्स के मानों तक पहुँचते हैं और उन फ़ील्ड्स को डेटाबेस कॉलम में इकाई के JavaBean प्रॉपर्टी एक्सेसर (गेट्टर) और म्यूटेटर (सेटर) विधियों का उपयोग करके मैप करते हैं। जैसे, एक इकाई में निजी क्षेत्रों के नाम और प्रकार जेपीए के लिए कोई मायने नहीं रखते। इसके बजाय, JPA केवल नाम और रिटर्न प्रकार के JavaBean प्रॉपर्टी ऐक्सेसर्स को देखता है। आप @javax.persistence.Access
एनोटेशन का उपयोग करके इसे बदल सकते हैं , जो आपको उस पहुंच पद्धति को स्पष्ट रूप से निर्दिष्ट करने में सक्षम बनाता है जिसे जेपीए प्रदाता को नियोजित करना चाहिए।
@Entity
@Access(AccessType.FIELD)
public class SomeEntity implements Serializable
{
...
}
AccessType enum के लिए उपलब्ध विकल्प PROPERTY (डिफ़ॉल्ट) और FIELD हैं। PROPERTY के साथ, प्रदाता JavaBean संपत्ति विधियों का उपयोग करके फ़ील्ड मान प्राप्त करता है और सेट करता है। FIELD प्रदाता को प्राप्त करता है और उदाहरण क्षेत्रों का उपयोग करके फ़ील्ड मान सेट करता है। एक सर्वोत्तम अभ्यास के रूप में, आपको केवल डिफ़ॉल्ट रूप से चिपके रहना चाहिए और JavaBean गुणों का उपयोग करना चाहिए जब तक कि आपके पास अन्यथा करने के लिए एक सम्मोहक कारण न हो।
आप इन संपत्ति एनोटेशन को निजी क्षेत्रों या सार्वजनिक एक्सेसर विधियों पर डाल सकते हैं। यदि आप AccessType.PROPERTY
जावा बीन एक्सेसर्स के बजाय निजी फ़ील्ड्स का उपयोग (डिफॉल्ट) करते हैं और एनोटेट करते हैं, तो फ़ील्ड नामों को JavaBean संपत्ति के नामों से मेल खाना चाहिए। हालाँकि, अगर आप JavaBean एक्सेसर्स एनोटेट करते हैं तो नामों का मिलान नहीं होता है। इसी तरह, यदि आप AccessType.FIELD
खेतों के बजाय JavaBean एक्सेसर्स का उपयोग और एनोटेट करते हैं, तो फ़ील्ड नामों को भी JavaBean प्रॉपर्टी के नामों से मेल खाना चाहिए। इस मामले में, यदि आप खेतों को एनोटेट करते हैं, तो उनका मिलान नहीं होता है। यह सिर्फ सुसंगत होना और इसके लिए AccessType.PROPERTY
और इसके
लिए जावा बीन एक्सेसर्स को एनोटेट करना सबसे अच्छा है AccessType.FIELD
।
यह महत्वपूर्ण है कि आपको कभी भी एक ही इकाई में जेपीए संपत्ति एनोटेशन और जेपीए फील्ड एनोटेशन को मिश्रण नहीं करना चाहिए। ऐसा करने से अनिर्दिष्ट व्यवहार होता है और त्रुटियों की संभावना होती है।
यह एक पुरानी प्रस्तुति है, लेकिन रॉड का सुझाव है कि संपत्ति के उपयोग पर एनोटेशन एनीमिक डोमेन मॉडल को प्रोत्साहित करता है और एनोटेट करने का "डिफ़ॉल्ट" तरीका नहीं होना चाहिए।
फ़ील्ड एक्सेस के पक्ष में एक और बिंदु यह है कि अन्यथा आप संग्रह के लिए बसने वालों को भी बेनकाब करने के लिए मजबूर हैं, मेरे लिए, हाइबरनेट द्वारा प्रबंधित ऑब्जेक्ट के लिए लगातार संग्रह उदाहरण को बदलने के रूप में एक बुरा विचार नहीं है, निश्चित रूप से आपके डेटा संगतता को तोड़ देगा।
इसलिए मैं डिफ़ॉल्ट कंस्ट्रक्टर में खाली कार्यान्वयन के लिए संरक्षित क्षेत्रों के रूप में संग्रह करना पसंद करता हूं और केवल अपने गेटर्स को उजागर करता हूं। की तरह फिर, केवल प्रबंधित संचालन clear()
, remove()
, removeAll()
आदि संभव है कि हाइबरनेट परिवर्तन के बारे में पता कर कभी नहीं होगा रहे हैं।
मैं खेतों को पसंद करता हूं, लेकिन मैं एक स्थिति में भाग गया हूं जो मुझे गेटर्स पर एनोटेशन लगाने के लिए मजबूर करता है।
हाइबरनेट जेपीए कार्यान्वयन के साथ, @Embedded
खेतों पर काम करना संभव नहीं लगता है। ताकि गेट पर जाना पड़े। और एक बार जब आप इसे गेट पर रख देते हैं, तो विभिन्न @Column
एनोटेशन को गेटर्स पर भी जाना पड़ता है। (मुझे लगता है कि हाइबरनेट यहां फ़ील्ड और गेटर्स को मिलाना नहीं चाहता है।) और एक बार जब आप @Column
गेटर्स को एक क्लास में डाल रहे होते हैं , तो संभवत: ऐसा करने के लिए समझ में आता है।
मैं फील्ड एक्सेसर्स का पक्ष लेता हूं। कोड बहुत क्लीनर है। सभी एनोटेशन को एक वर्ग के एक भाग में रखा जा सकता है और कोड को पढ़ना बहुत आसान है।
मुझे प्रॉपर्टी ऐक्सेसर्स के साथ एक और समस्या देखने को मिली: यदि आपके पास अपनी क्लास में गेटएक्सवाईजेड तरीके हैं जो लगातार संपत्तियों से जुड़े होने के रूप में एनोटेट नहीं हैं, तो हाइबरनेट उन गुणों को प्राप्त करने के लिए एसक्यूएल उत्पन्न करता है, जिसके परिणामस्वरूप कुछ बहुत ही भ्रामक त्रुटि संदेश मिलते हैं। दो घंटे बर्बाद। मैंने यह कोड नहीं लिखा था; मैंने हमेशा अतीत में फ़ील्ड एक्सेसर्स का उपयोग किया है और इस मुद्दे पर कभी नहीं चला।
इस ऐप में उपयोग किए गए हाइबरनेट संस्करण:
<!-- hibernate -->
<hibernate-core.version>3.3.2.GA</hibernate-core.version>
<hibernate-annotations.version>3.4.0.GA</hibernate-annotations.version>
<hibernate-commons-annotations.version>3.1.0.GA</hibernate-commons-annotations.version>
<hibernate-entitymanager.version>3.4.0.GA</hibernate-entitymanager.version>
आपको संपत्तियों के माध्यम से पहुंच से अधिक क्षेत्रों तक पहुंच का चयन करना चाहिए। फ़ील्ड के साथ आप भेजे और प्राप्त किए गए डेटा को सीमित कर सकते हैं। गुणों के माध्यम से आप एक मेजबान के रूप में अधिक डेटा भेज सकते हैं, और जी संप्रदायों को सेट कर सकते हैं (जो कारखाना कुल गुणों में से अधिकांश सेट करता है)।
हाइबरनेट में accesstype के संबंध में मेरा एक ही सवाल था और यहाँ कुछ उत्तर मिले ।
मैंने आलसी प्रारंभिककरण और क्षेत्र अभिगम को हल कर दिया है यहां हाइबरनेट एक-से-एक: getId () पूरे ऑब्जेक्ट को प्राप्त किए बिना
हमने इकाई बीन्स बनाए और गेट्टर एनोटेशन का उपयोग किया। समस्या यह है कि हम भाग चुके हैं: कुछ संस्थाओं के पास कुछ संपत्तियों के लिए जटिल नियम हैं जब उन्हें अपडेट किया जा सकता है। समाधान के लिए प्रत्येक सेटर में कुछ व्यावसायिक तर्क थे जो यह निर्धारित करते हैं कि वास्तविक मूल्य बदल गया है या नहीं, यदि ऐसा है, तो परिवर्तन को अनुमति दी जानी चाहिए या नहीं। बेशक, हाइबरनेट हमेशा गुण सेट कर सकता है, इसलिए हमने दो समूहों के साथ समझौता किया। बहुत बदसूरत।
पिछली पोस्टों को पढ़ते हुए, मैं यह भी देखता हूं कि इकाई के अंदर से संपत्तियों को संदर्भित करना संग्रह को लोड न करने के मुद्दों को जन्म दे सकता है।
नीचे की रेखा, मैं भविष्य में खेतों की व्याख्या करने की ओर झुकूंगा।
आम तौर पर सेम POJO होते हैं, इसलिए उनके पास वैसे भी एक्सेसर्स होते हैं।
तो सवाल यह नहीं है कि "कौन सा बेहतर है?", लेकिन बस "जब क्षेत्र का उपयोग करना है?"। और जवाब "जब आपको फ़ील्ड के लिए एक सेटर / गेट्टर की आवश्यकता नहीं है!"।
मैं इस बारे में सोच रहा हूं और मैं मेथड एसेसर चुन रहा हूं
क्यों?
क्योंकि फ़ील्ड और मेथोस एक्सेसर समान है लेकिन अगर बाद में मुझे लोड फ़ील्ड में कुछ तर्क की आवश्यकता होती है, तो मैं खेतों में रखे सभी एनोटेशन को स्थानांतरित करता हूं
सादर
Grubhart
दोनों:
EJB3 युक्ति के लिए आवश्यक है कि आप उस तत्व प्रकार पर एनोटेशन की घोषणा करें, जिसे एक्सेस किया जाएगा, अर्थात यदि आप प्रॉपर्टी एक्सेस, फ़ील्ड का उपयोग करते हैं, तो यदि आप फ़ील्ड एक्सेस का उपयोग करते हैं, तो गेट्टर विधि।
https://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#entity-mapping
AccessType.PROPERTY: EJB दृढ़ता कार्यान्वयन JavaBean "सेटर" विधियों के माध्यम से आपकी कक्षा में स्थिति को लोड करेगा, और JavaBean "गेट्टर" विधियों का उपयोग करके अपनी कक्षा से राज्य को पुनः प्राप्त करेगा। यह डिफ़ॉल्ट है।
AccessType.FIELD: राज्य को आपकी कक्षा के क्षेत्रों से सीधे लोड और पुनर्प्राप्त किया जाता है। आपको जावाबीन "गेटर्स" और "सेटर्स" लिखना नहीं है।