java - Hibernate hbm2ddl.auto संभावित मान और वे क्या करते हैं?
(9)
कॉन्फ़िगरेशन प्रॉपर्टी को hibernate.hbm2ddl.auto
कहा जाता hibernate.hbm2ddl.auto
हमारे विकास पर्यावरण में हम hibernate.hbm2ddl.auto=create-drop
को ड्रॉप और ड्रॉप करते समय प्रत्येक बार एक स्वच्छ डेटाबेस बनाते हैं, ताकि हमारा डेटाबेस ज्ञात स्थिति में हो।
सिद्धांत रूप में, आप अपने मॉडल में परिवर्तन के साथ अपने डेटाबेस को hibernate.hbm2ddl.auto=update
करने के लिए hibernate.hbm2ddl.auto=update
सेट कर सकते हैं, लेकिन मैं उस पर उत्पादन डेटाबेस पर भरोसा नहीं करता। दस्तावेज के एक पुराने संस्करण ने कहा कि यह कम से कम प्रयोगात्मक था; मुझे वर्तमान स्थिति नहीं पता है।
इसलिए, हमारे उत्पादन डेटाबेस के लिए, hibernate.hbm2ddl.auto
सेट न करें - डिफ़ॉल्ट डेटाबेस परिवर्तन नहीं करना है। इसके बजाए, हम मैन्युअल रूप से एक SQL DDL अद्यतन स्क्रिप्ट बनाते हैं जो एक संस्करण से अगले संस्करण में परिवर्तन लागू करता है।
मैं वास्तव में अद्यतन, निर्यात और मूल्यों के बारे में अधिक जानना चाहता हूं जो hibernate.hbm2ddl.auto
को दिए जा सकते hibernate.hbm2ddl.auto
मुझे पता होना चाहिए कि अद्यतन का उपयोग कब करें और कब नहीं? और विकल्प क्या है?
ये परिवर्तन हैं जो डीबी पर हो सकते हैं:
- नई टेबल
- पुरानी टेबल में नए कॉलम
- कॉलम हटा दिए गए
- कॉलम का डेटा प्रकार बदल गया
- एक कॉलम के एक प्रकार ने इसे गुण बदल दिया
- टेबल गिरा दिया गया है
- कॉलम के मान बदल गए हैं
प्रत्येक मामले में सबसे अच्छा समाधान क्या है?
पूरी तरह अक्षम करने के लिए "none" का अनियंत्रित मान भी है।
मुझे लगता है कि आपको ध्यान देना चाहिए
SchemaExport Class
यह कक्षा आपके कॉन्फ़िगरेशन गतिशील बनाता है, इसलिए यह आपको जो भी सुइट्स चुनता है उसे चुनने की अनुमति देता है ...
चेकआउट [SchemaExport]
मैं आपके डीबी को अद्यतन करने के लिए तरल पदार्थ का उपयोग करूंगा। हाइबरनेट की स्कीमा अपडेट सुविधा वास्तव में केवल डेवलपर के लिए ठीक है, जबकि वे नई सुविधाएं विकसित कर रहे हैं। उत्पादन की स्थिति में, डीबी अपग्रेड को अधिक सावधानीपूर्वक संभालने की आवश्यकता है।
यदि आप अपने ऐप में स्ट्रिंग्स का उपयोग नहीं करना चाहते हैं और पूर्वनिर्धारित स्थिरांक की तलाश में हैं तो org.hibernate.cfg.AvailableSettings
पर एक नज़र डालें। उपलब्ध org.hibernate.cfg.AvailableSettings
क्लास हाइबरनेट जेएआर में शामिल है, जहां आपको सभी संभावित सेटिंग्स के लिए निरंतर मिल जाएगा। उदाहरण के लिए आपके मामले में:
/**
* Auto export/update schema using hbm2ddl tool. Valid values are <tt>update</tt>,
* <tt>create</tt>, <tt>create-drop</tt> and <tt>validate</tt>.
*/
String HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
यद्यपि यह काफी पुरानी पोस्ट है, लेकिन जैसा कि मैंने इस विषय पर कुछ शोध किया है, इसलिए इसे साझा करने के बारे में सोचा।
hibernate.hbm2ddl.auto
दस्तावेज के अनुसार इसमें चार वैध मान हो सकते हैं:
बनाएँ | अपडेट करें | मान्य करें | बनाने ड्रॉप
इन मानों द्वारा दिखाए गए व्यवहार की व्याख्या निम्नलिखित है:
- बनाएं : - स्कीमा बनाएं, स्कीमा में पहले मौजूद डेटा (यदि वहां है) खो गया है
- अद्यतन करें: - दिए गए मानों के साथ स्कीमा अपडेट करें।
- मान्य करें: - स्कीमा को मान्य करें। यह डीबी में कोई बदलाव नहीं करता है।
- निर्माण-ड्रॉप: - पहले मौजूद डेटा को नष्ट करने के साथ स्कीमा बनाएं (यदि वहां है)। सत्र फैक्ट्री बंद होने पर यह डेटाबेस स्कीमा भी छोड़ देता है।
ध्यान देने योग्य महत्वपूर्ण बिंदु निम्नलिखित हैं:
- अद्यतन के मामले में, यदि स्कीमा डीबी में मौजूद नहीं है तो स्कीमा बनाया गया है।
- वैध होने के मामले में, यदि डीबी में स्कीमा मौजूद नहीं है, तो यह नहीं बनाया गया है। इसके बजाए, यह एक त्रुटि फेंक देगा: -
Table not found:<table name>
- निर्माण-ड्रॉप के मामले में, सत्र बंद करने पर स्कीमा नहीं छोड़ा गया है। यह केवल सत्र फैक्ट्री को बंद करने पर ही गिरता है।
यदि मैं इस संपत्ति के लिए कोई मूल्य देता हूं (ऊपर चर्चा की गई चार मूल्यों के बजाय एबीसी कहें) या यह अभी खाली है। यह निम्नलिखित व्यवहार दिखाता है:
-यदि स्कीमा डीबी में मौजूद नहीं है: - यह स्कीमा बनाता है
- अगर स्कीमा डीबी में मौजूद है: - स्कीमा अपडेट करें।
सिद्धांत रूप में, आप अपने मॉडल में परिवर्तन के साथ अपने डेटाबेस को अद्यतन करने के लिए hibernate.hbm2ddl.auto = अद्यतन सेट कर सकते हैं, लेकिन मैं उस पर उत्पादन डेटाबेस पर भरोसा नहीं करता। दस्तावेज के एक पुराने संस्करण ने कहा कि यह कम से कम प्रयोगात्मक था; मुझे वर्तमान स्थिति नहीं पता है।
इसलिए, हमारे उत्पादन डेटाबेस के लिए, hibernate.hbm2ddl.auto सेट न करें - डिफ़ॉल्ट डेटाबेस परिवर्तन नहीं करना है। इसके बजाए, हम मैन्युअल रूप से एक SQL DDL अद्यतन स्क्रिप्ट बनाते हैं जो एक संस्करण से अगले संस्करण में परिवर्तन लागू करता है।
hibernate.hbm2ddl.auto सत्र फ़ैक्टरी बनने पर डेटाबेस को स्कीमा डीडीएल स्वचालित रूप से मान्य या निर्यात करता है। बिल्ड-ड्रॉप के साथ, सत्र फ़ैक्टरी स्पष्ट रूप से बंद होने पर डेटाबेस स्कीमा को हटा दिया जाएगा।
उदाहरण के लिए मान्य करें अपडेट करें | बनाएँ | बनाने ड्रॉप
तो संभावित विकल्पों की सूची हैं,
- मान्य करें : स्कीमा को मान्य करें, डेटाबेस में कोई बदलाव नहीं करता है।
- अद्यतन : स्कीमा अपडेट करें।
- बनाएँ : पिछले डेटा को नष्ट करने, स्कीमा बनाता है।
- बिल्ड -ड्रॉप : स्कीमा ड्रॉप करें जब सत्र फैक्ट्री स्पष्ट रूप से बंद हो जाती है, आमतौर पर जब एप्लिकेशन बंद हो जाता है।
ये विकल्प डेवलपर टूल बनने के लिए प्रतीत होते हैं और किसी भी उत्पादन स्तर डेटाबेस को सुविधाजनक बनाने के लिए नहीं, आप निम्न प्रश्नों को देखना चाहते हैं; हाइबरनेट: hbm2ddl.auto = उत्पादन में अद्यतन?
5.0 के बाद से , अब आप उन मानों को समर्पित org.hibernate.boot.SchemaAutoTooling
: org.hibernate.boot.SchemaAutoTooling
(5.2 के बाद से मूल्य के साथ बढ़ाया गया) में पा सकते हैं।
या इससे भी बेहतर, 5.1 के बाद से , आप org.hibernate.tool.schema.Action
Enum
का भी उपयोग कर सकते हैं जो जेपीए 2 और "विरासत" हाइबरनेट डीडीएल क्रियाओं को जोड़ती है।
लेकिन , आप अभी तक DataSource
प्रोग्रामेटिक रूप से कॉन्फ़िगर नहीं कर सकते हैं। यह org.hibernate.cfg.AvailableSettings#HBM2DDL_AUTO
के साथ संयुक्त का उपयोग करने के लिए अच्छा होगा लेकिन वर्तमान कोड एक String
मान ( org.hibernate.cfg.AvailableSettings#HBM2DDL_AUTO
से लिया गया अंश) की अपेक्षा करता है:
this.schemaAutoTooling = SchemaAutoTooling.interpret( (String) configurationSettings.get( AvailableSettings.HBM2DDL_AUTO ) );
... और दोनों org.hibernate.boot.SchemaAutoTooling
और org.hibernate.tool.schema.Action
आंतरिक enum
मान सार्वजनिक रूप से खुलासा नहीं किया जाता है।
यहां, एक नमूना प्रोग्रामैटिक DataSource
कॉन्फ़िगरेशन (मेरे स्प्रिंग बूट अनुप्रयोगों में से एक में उपयोग किया जाता है) जो एक .name().toLowerCase()
उपयोग करता है .name().toLowerCase()
पर यह केवल डैश के बिना मूल्यों के साथ काम करता है (उदाहरण के लिए create-drop
नहीं):
@Bean(name = ENTITY_MANAGER_NAME)
public LocalContainerEntityManagerFactoryBean internalEntityManagerFactory(
EntityManagerFactoryBuilder builder,
@Qualifier(DATA_SOURCE_NAME) DataSource internalDataSource) {
Map<String, Object> properties = new HashMap<>();
properties.put(AvailableSettings.HBM2DDL_AUTO, SchemaAutoTooling.CREATE.name().toLowerCase());
properties.put(AvailableSettings.DIALECT, H2Dialect.class.getName());
return builder
.dataSource(internalDataSource)
.packages(JpaModelsScanEntry.class, Jsr310JpaConverters.class)
.persistenceUnit(PERSISTENCE_UNIT_NAME)
.properties(properties)
.build();
}