java - हाइबरनेट: hbm2ddl.auto=उत्पादन में अद्यतन?




hibernate (11)

क्या उत्पादन वातावरण में डेटाबेस स्कीमा को अद्यतन करने के लिए hbm2ddl.auto=update साथ कॉन्फ़िगर किए गए हाइबरनेट अनुप्रयोगों को चलाने के लिए ठीक है?


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

स्कीमा विकास को नियंत्रण में रखने के लिए हाइबरनेट मैपिंग्स (या एनोटेशन) में आपकी सभी दृढ़ता रखने का एक बहुत अच्छा तरीका है।

आपको यह समझना चाहिए कि स्कीमा विकास के कई पहलुओं पर विचार किया जाना चाहिए:

  1. अधिक कॉलम और तालिकाओं को जोड़ने में डेटाबेस स्कीमा का विकास

  2. पुराने कॉलम, टेबल और रिश्तों को छोड़ना

  3. डिफ़ॉल्ट के साथ नए कॉलम भरना

विशेष रूप से हाइबरनेट उपकरण महत्वपूर्ण हैं (जैसे मेरे अनुभव में) आपके पास कई अलग-अलग प्रकार के डेटाबेस पर एक ही एप्लिकेशन के विभिन्न संस्करण हैं।

यदि आप हाइबरनेट का उपयोग कर रहे हैं तो प्वाइंट 3 बहुत संवेदनशील है, जैसे कि यदि आप एक नई बूलियन मूल्यवान संपत्ति या संख्यात्मक एक परिचय देते हैं, तो यदि हाइबरनेट को ऐसे कॉलम में कोई शून्य मान मिलेगा, तो अपवाद उठाएगा।

तो मैं क्या करूँगा: वास्तव में स्कीमा अपडेट की हाइबरनेट टूल क्षमता का उपयोग करें, लेकिन आपको इसके साथ कुछ डेटा और स्कीमा रखरखाव कॉलबैक जोड़ना होगा, जैसे डिफ़ॉल्ट भरने, अब कॉलम का उपयोग नहीं करना, और इसी तरह के। इस तरह आप फायदे (डाटाबेस स्वतंत्र स्कीमा अपडेट स्क्रिप्ट्स और अद्यतनों के डुप्लिकेट कोडिंग से बचते हैं, पर्सिस्टेंस और स्क्रिप्ट में) लेकिन आप ऑपरेशन के सभी पहलुओं को भी कवर करते हैं।

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

यह माना जा रहा है कि अद्यतन होने पर एप्लिकेशन अपनी स्कीमा को अपडेट करने में सक्षम है (यह किया जा सकता है), जिसका अर्थ यह भी है कि स्कीमा पर ऐसा करने के लिए उपयोगकर्ता अधिकार होना चाहिए। यदि ग्राहक की नीति इस (संभावित छिपकली मस्तिष्क मामले) को रोकती है, तो आपको डेटाबेस-विशिष्ट स्क्रिप्ट प्रदान करना होगा।


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

असल में, आप उन परिवर्तनों की एक XML फ़ाइल रखते हैं जिन्हें आप जोड़ना जारी रखते हैं क्योंकि आपका एप्लिकेशन विकसित होता है। यह फ़ाइल आपके बाकी प्रोजेक्ट के साथ गिट (या जो भी आप उपयोग कर रहे हैं) में रखी गई है। जब आपका ऐप तैनात किया जाता है, तो Liquibase उस डीबी में अपनी चेंजलॉग तालिका की जांच करता है जिसे आप कनेक्ट कर रहे हैं ताकि यह पता चल सके कि पहले से ही क्या लागू किया जा चुका है, तो यह समझदारी से लागू होता है कि फ़ाइल से अभी भी जो भी परिवर्तन लागू नहीं किए गए हैं। यह अभ्यास में बिल्कुल बढ़िया काम करता है, और यदि आप इसे अपने सभी स्कीमा परिवर्तनों के लिए उपयोग करते हैं, तो आप 100% आत्मविश्वास प्राप्त कर सकते हैं कि आपके द्वारा चेकआउट और तैनाती कोड हमेशा पूरी तरह से संगत डेटाबेस स्कीमा से कनेक्ट हो पाएगा।

भयानक बात यह है कि मैं अपने लैपटॉप पर एक पूरी तरह से रिक्त स्लेट MySQL डेटाबेस ले सकता हूं, ऐप को फायर कर सकता हूं, और तुरंत मेरे लिए स्कीमा सेट अप किया गया है। यह इन्हें स्थानीय-देव या स्टेजिंग डीबी में लागू करके स्कीमा परिवर्तनों का परीक्षण करना भी आसान बनाता है।

इसके साथ शुरू करने का सबसे आसान तरीका शायद आपके मौजूदा डीबी को लेना होगा और फिर प्रारंभिक बेसलाइन.एक्सएमएल फ़ाइल उत्पन्न करने के लिए लिक्विबेस का उपयोग करना होगा। फिर भविष्य में आप इसे जोड़ सकते हैं और स्कीमा परिवर्तनों को प्रबंधित करने के लिए तरल पदार्थ ले सकते हैं।

http://www.liquibase.org/


नहीं, इसे कभी मत करो। हाइबरनेट डेटा माइग्रेशन को संभाल नहीं करता है। हां, यह आपकी स्कीमा को सही तरीके से देखेगा लेकिन यह सुनिश्चित नहीं करता है कि प्रक्रिया में मूल्यवान उत्पादन डेटा खो नहीं गया है।


नहीं, यह असुरक्षित है।

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

सैद्धांतिक रूप से, अगर एचबीएम 2ddl अद्यतन विकास में काम करता है, तो इसे भी उत्पादन में काम करना चाहिए। लेकिन हकीकत में, यह हमेशा मामला नहीं है।

भले ही यह ठीक काम करता है, यह उप-इष्टतम हो सकता है। एक कारण के लिए डीबीए का भुगतान किया जाता है।


मैं इसे जोखिम नहीं दूंगा क्योंकि आप डेटा खोने को समाप्त कर सकते हैं जिसे संरक्षित किया जाना चाहिए था। hbm2ddl.auto = अद्यतन अपने dev डेटाबेस को अद्यतित रखने का एक आसान तरीका है।


मैं वोट नहीं दूंगा। हाइबरनेट को समझ में नहीं आता है जब स्तंभों के लिए डेटाटाइप बदल गए हैं। उदाहरण (MySQL का उपयोग करके):

String with @Column(length=50)  ==> varchar(50)
changed to
String with @Column(length=100) ==> still varchar(50), not changed to varchar(100)

@Temporal(TemporalType.TIMESTAMP,TIME,DATE) will not update the DB columns if changed

शायद अन्य उदाहरण भी हैं, जैसे 255 से अधिक स्ट्रिंग कॉलम की लंबाई को धक्का देना और इसे टेक्स्ट, मध्यम टेक्स्ट इत्यादि में परिवर्तित करना।

अनुमोदित, मुझे नहीं लगता कि वास्तव में एक नया कॉलम बनाये बिना डेटा को कॉपी करने और पुराने कॉलम को उड़ाने के साथ "डेटाटाइप को कन्वर्ट करने" का एक तरीका है। लेकिन आपके डेटाबेस में ऐसे कॉलम हैं जो वर्तमान हाइबरनेट मैपिंग को प्रतिबिंबित नहीं करते हैं, आप बहुत खतरनाक रूप से रह रहे हैं ...

इस समस्या से निपटने के लिए फ्लाईवे एक अच्छा विकल्प है:

http://flywaydb.org


यह सुरक्षित नहीं है, अनुशंसित नहीं है, लेकिन यह संभव है।

मुझे उत्पादन में ऑटो-अपडेट विकल्प का उपयोग करके एक एप्लिकेशन में अनुभव है।

खैर, इस समाधान में पाए जाने वाली मुख्य समस्याएं और जोखिम हैं:

  • गलत डेटाबेस में तैनात करें । यदि आप गलत डेटाबेस में एप्लिकेशन के पुराने संस्करण (EAR / WAR / etc) के साथ अनुप्रयोग सर्वर को चलाने के लिए गलती करते हैं ... आपके पास बहुत से नए कॉलम, टेबल, विदेशी कुंजी और त्रुटियां होंगी। डेटासॉर फ़ाइल में एक साधारण गलती के साथ एक ही समस्या हो सकती है, (फ़ाइल कॉपी / पेस्ट करें और डेटाबेस को बदलने के लिए भूल गए)। फिर से शुरू करने के लिए, स्थिति आपके डेटाबेस में एक आपदा हो सकती है।
  • एप्लिकेशन सर्वर को शुरू करने में बहुत लंबा समय लगता है । ऐसा इसलिए होता है क्योंकि हर बार जब आप एप्लिकेशन शुरू करते हैं तो हाइबरनेट सभी बनाई गई तालिकाओं / कॉलम / आदि को खोजने का प्रयास करता है। वह यह जानने के लिए करता है कि (टेबल, कॉलम, आदि) को कैसे बनाया जाना चाहिए। यह समस्या केवल बदतर हो जाएगी।
  • डाटाबेस टूल्स का उपयोग करना लगभग असंभव है । डेटाबेस के लिए स्क्रिप्ट बनाने के लिए, आपको एप्लिकेशन सर्वर शुरू करने के बाद ऑटो-अपडेट द्वारा क्या बनाया जाएगा इसके बारे में सोचना होगा। यदि आपको कुछ डेटा के साथ एक नया कॉलम (प्रति उदाहरण) भरने की आवश्यकता है, तो आपको एप्लिकेशन सर्वर शुरू करने की आवश्यकता है, नए कॉलम को हाइबरनेट करने के लिए प्रतीक्षा करें और इसके बाद SQL स्क्रिप्ट चलाएं। फ्लाईवे जैसे टूल्स ऑटो-अपडेट सक्षम के साथ उपयोग करना लगभग असंभव है।
  • डेटाबेस परिवर्तन केंद्रीकृत नहीं है । हाइबरनेट की संभावनाओं के साथ तालिकाओं और अन्य सभी चीजों को बनाने के साथ, एप्लिकेशन के प्रत्येक संस्करण में डेटाबेस पर परिवर्तन देखना मुश्किल है, क्योंकि उनमें से अधिकतर स्वचालित रूप से होते हैं।
  • डेटाबेस पर कचरा प्रोत्साहित करता है । ऑटो-अपडेट की आसानी के कारण, आपकी टीम पुराने कॉलम और पुरानी टेबल को छोड़ने की उपेक्षा कर रही है।
  • आसन्न आपदा उत्पादन में होने वाली कुछ आपदाओं का आसन्न जोखिम (जैसे अन्य उत्तरों में उल्लिखित कुछ लोगों)। यहां तक ​​कि कई वर्षों तक चलने वाले और अद्यतन करने योग्य एप्लिकेशन के साथ, मुझे नहीं लगता कि यह सुरक्षित है। मैंने कभी सुरक्षित महसूस नहीं किया।

इसलिए, मैं उत्पादन में ऑटो-अपडेट का उपयोग करने की अनुशंसा नहीं करूंगा।

यदि आप वास्तव में उत्पादन में ऑटो-अपडेट का उपयोग करना चाहते हैं, तो मैं अनुशंसा करता हूं:

  • अलग नेटवर्क आपका परीक्षण वातावरण होमोलॉग पर्यावरण तक नहीं पहुंच सकता है। यह परीक्षण वातावरण में होने वाली तैनाती को रोकने में मदद करता है जो होमोलॉगेशन डेटाबेस बदलता है।
  • स्क्रिप्ट ऑर्डर प्रबंधित करें । तैनाती के बाद आपको अपनी तैयारी (संरचना तालिका परिवर्तन, ड्रॉप टेबल / कॉलम) और स्क्रिप्ट से पहले चलाने के लिए अपनी स्क्रिप्ट को व्यवस्थित करने की आवश्यकता है (नए कॉलम / टेबल के लिए जानकारी भरें)।

और, एक और पोस्ट के अलावा, मुझे नहीं लगता कि ऑटो-अपडेट सक्षम है, यह "बहुत अच्छी तरह से भुगतान" डीबीए (जैसा कि अन्य पदों में उल्लिखित है) से संबंधित है ... एसक्यूएल स्टेटमेंट बनाने के लिए डीबीए के पास अधिक महत्वपूर्ण चीजें हैं / टेबल / कॉलम बदलें / हटाएं। इन साधारण रोज़गार कार्यों को डेवलपर्स द्वारा किया जा सकता है और स्वचालित किया जा सकता है और केवल डीबीए टीम के लिए समीक्षा करने के लिए पास किया जा सकता है, उन्हें लिखने के लिए हाइबरनेट और डीबीए "बहुत अच्छी तरह से भुगतान" की आवश्यकता नहीं है।


हम इसे एक ऐसे आवेदन के साथ उत्पादन में करते हैं जो मिशन को महत्वपूर्ण नहीं है और कर्मचारियों पर अत्यधिक भुगतान किए गए डीबीए के साथ नहीं है। यह केवल एक कम मैन्युअल प्रक्रिया है जो मानव त्रुटि के अधीन है - एप्लिकेशन अंतर का पता लगा सकता है और सही काम कर सकता है, साथ ही आपने इसे विभिन्न विकास और परीक्षण वातावरण में संभवतः परीक्षण किया है।

एक चेतावनी - एक क्लस्टर वातावरण में आप इससे बचना चाह सकते हैं क्योंकि एक ही समय में कई ऐप्स आ सकते हैं और स्कीमा को संशोधित करने का प्रयास कर सकते हैं जो खराब हो सकता है। या कुछ तंत्र में डालें जहां स्कीमा को अपडेट करने के लिए केवल एक उदाहरण की अनुमति है।


हाइबरनेट को खुद को कवर करने के लिए प्रोड में ऑटो अपडेट का उपयोग न करने के बारे में अस्वीकरण करना पड़ता है, जब लोग नहीं जानते कि वे क्या कर रहे हैं, जहां वे इसका उपयोग नहीं कर रहे हैं, जहां इसे इस्तेमाल नहीं किया जाना चाहिए।

उन स्थितियों को अनुमोदित किया जहां इसका उपयोग नहीं किया जाना चाहिए, जहां यह ठीक है वहां से कहीं अधिक है।

मैंने कई वर्षों से विभिन्न परियोजनाओं पर इसका इस्तेमाल किया है और कभी भी एक ही मुद्दा नहीं था। यह एक लंगड़ा जवाब नहीं है, और यह काउबॉय कोडिंग नहीं है। यह एक ऐतिहासिक तथ्य है।

एक व्यक्ति जो "उत्पादन में कभी नहीं करता" कहता है, उत्पादन तैनाती के एक विशिष्ट सेट के बारे में सोच रहा है, अर्थात् वह जिनके साथ वह परिचित है (उनकी कंपनी, उनका उद्योग, आदि)।

"उत्पादन तैनाती" का ब्रह्मांड विशाल और विविध है।

एक अनुभवी हाइबरनेट डेवलपर जानता है कि डीडीएल किसी दिए गए मैपिंग कॉन्फ़िगरेशन से क्या परिणाम दे रहा है। जब तक आप डीडीएल (देव, क्यूए, स्टेजिंग इत्यादि) में समाप्त होने की अपेक्षा करते हैं, तो आप परीक्षण और सत्यापन करते हैं, तो आप ठीक हैं।

जब आप बहुत सारी सुविधाएं जोड़ रहे हैं, तो ऑटो स्कीमा अपडेट वास्तविक समय बचतकर्ता हो सकते हैं।

सामान ऑटो अपडेट की सूची अंतहीन नहीं होगी, लेकिन कुछ उदाहरण डेटा माइग्रेशन हैं, गैर-शून्य कॉलम, कॉलम नाम परिवर्तन इत्यादि शामिल हैं।

इसके अलावा आपको क्लस्टर वातावरण में देखभाल करने की आवश्यकता है।

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


हाइबरनेट निर्माता अपनी पुस्तक "जावा पर्सिस्टेंस विद हाइबरनेट" में उत्पादन वातावरण में ऐसा करने से हतोत्साहित करते हैं:

चेतावनी: हमने हाइबरनेट उपयोगकर्ताओं को स्वचालित रूप से उत्पादन डेटाबेस की स्कीमा अपडेट करने के लिए SchemaUpdate का उपयोग करने का प्रयास किया है। यह आपदा में जल्दी खत्म हो सकता है और आपके डीबीए द्वारा इसकी अनुमति नहीं दी जाएगी।


  • मेरे मामले में (हाइबरनेट 3.5.2, पोस्टग्रेस्क्ल, उबंटू), hibernate.hbm2ddl.auto=update केवल नई टेबल बनाई गई है और पहले से मौजूद टेबल में नए कॉलम बनाए हैं।

  • यह न तो टेबल छोड़ देता है, न ही कॉलम ड्रॉप करता है, न ही कॉलम बदलता है। इसे एक सुरक्षित विकल्प कहा जा सकता है, लेकिन कुछ hibernate.hbm2ddl.auto=create_tables add_columns अधिक स्पष्ट होगा।





hbm2ddl