java - हाइबरनेट, @ सिकेंस जेनरेटर और आवंटन आकार




hibernate jpa (4)

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

हालांकि, उस व्यवहार को पाने का विकल्प है जिसे आप ढूंढ रहे हैं। सबसे पहले मेरा जवाब देखें क्या जेपीए एनोटेशन और हाइबरनेट का उपयोग करके @GeneratedValue रणनीति को गतिशील रूप से चुनने का कोई तरीका है? यह आपको मूल बातें देगा। जब तक आप उस अनुक्रम स्टाइल जेनरेटर का उपयोग करने के लिए सेट अप किए जाते हैं, तब तक हाइबरनेट SequenceStyleGenerator में "पूल किए गए अनुकूलक" का उपयोग करके allocationSize आकार की व्याख्या करेगा। "पूल किए गए ऑप्टिमाइज़र" डेटाबेस के साथ उपयोग के लिए है जो अनुक्रमों के निर्माण पर "वृद्धि" विकल्प की अनुमति देता है (अनुक्रमों का समर्थन करने वाले सभी डेटाबेस जो वृद्धि का समर्थन नहीं करते हैं)। वैसे भी, विभिन्न अनुकूलक रणनीतियों के बारे में पढ़ें।

हम सभी को @SequenceGenerator का उपयोग करते समय हाइबरनेट के डिफ़ॉल्ट व्यवहार को पता है - यह वास्तविक डेटाबेस अनुक्रम को एक से बढ़ाता है, यह मान 50 से अधिक (डिफ़ॉल्ट allocationSize मान) - और फिर इस मान का उपयोग इकाई आईडी के रूप में करता है।

यह गलत व्यवहार और specification साथ संघर्ष है जो कहता है:

आवंटन आकार - (वैकल्पिक) अनुक्रम से क्रम संख्या आवंटित करते समय वृद्धि करने की राशि।

स्पष्ट होने के लिए: मैं जेनरेट की गई आईडी के बीच अंतराल के बारे में परेशान नहीं हूं।

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

क्या किसी को इस समस्या का कोई समाधान पता है ( allocationSize=1 सेट किए बिना और इस प्रकार प्रदर्शन को कमजोर कर रहा है)?

संपादित करें:
चीजों को स्पष्ट करने के लिए। यदि अंतिम सम्मिलित रिकॉर्ड में आईडी = 1 , तो एचबी अपनी नई इकाइयों के लिए मूल्य 51, 52, 53... उपयोग करता है लेकिन एक ही समय में: डेटाबेस में अनुक्रम का मान 2 सेट किया जाएगा। जब अन्य अनुप्रयोग उस अनुक्रम का उपयोग कर रहे हैं तो आसानी से त्रुटियों की ओर ले जा सकता है।

हाथ पर: विनिर्देश कहता है (मेरी समझ में) कि डेटाबेस अनुक्रम 51 सेट किया जाना चाहिए था और इस बीच एचबी को श्रेणी 2, 3 ... 50 से मूल्यों का उपयोग करना चाहिए 2, 3 ... 50


अद्यतन करें:
जैसा कि स्टीव एबरसोल ने नीचे बताया है: मेरे द्वारा वर्णित व्यवहार (और कई लोगों के लिए सबसे सहज) hibernate.id.new_generator_mappings=true सेट करके सक्षम किया जा सकता hibernate.id.new_generator_mappings=true

आप सभी का धन्यवाद।

अद्यतन 2:
भविष्य के पाठकों के लिए, नीचे आप एक कामकाजी उदाहरण पा सकते हैं।

@Entity
@Table(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USERS_SEQ")
    @SequenceGenerator(name = "USERS_SEQ", sequenceName = "SEQUENCE_USERS")
    private Long id;
}

persistence.xml

<persistence-unit name="testPU">
  <properties>
    <property name="hibernate.id.new_generator_mappings" value="true" />
  </properties>
</persistence-unit>

मैं स्कीमा में अनुक्रम के लिए डीडीएल की जांच करूंगा। जेपीए कार्यान्वयन केवल सही आवंटन आकार के अनुक्रम का निर्माण जिम्मेदार है। इसलिए, यदि आवंटन आकार 50 है तो आपके अनुक्रम में डीडीएल में 50 की वृद्धि होनी चाहिए।

यह मामला आम तौर पर आवंटन आकार 1 के अनुक्रम के निर्माण के साथ होता है, बाद में आवंटन आकार 50 (या डिफ़ॉल्ट) के लिए कॉन्फ़िगर किया गया है लेकिन अनुक्रम डीडीएल अद्यतन नहीं है।


हाइबरनेट स्रोत कोड में खोदने के बाद और कॉन्फ़िगरेशन के नीचे 50 आवेषण के बाद अगले मान के लिए ओरेकल डीबी पर जाता है। इसलिए प्रत्येक बार इसे कॉल करने पर अपना INST_PK_SEQ वृद्धि 50 बनाएं।

हाइबरनेट 5 का उपयोग नीचे रणनीति के लिए किया जाता है

http://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/Hibernate_User_Guide.html#identifiers-generators-sequence नीचे भी देखें

@Id
@Column(name = "ID")
@GenericGenerator(name = "INST_PK_SEQ", 
strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
parameters = {
        @org.hibernate.annotations.Parameter(
                name = "optimizer", value = "pooled-lo"),
        @org.hibernate.annotations.Parameter(
                name = "initial_value", value = "1"),
        @org.hibernate.annotations.Parameter(
                name = "increment_size", value = "50"),
        @org.hibernate.annotations.Parameter(
                name = SequenceStyleGenerator.SEQUENCE_PARAM, value = "INST_PK_SEQ"),
    }
)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "INST_PK_SEQ")
private Long id;

allocationSize=1 यह क्वेरी प्राप्त करने से पहले एक माइक्रो ऑप्टिमाइज़ेशन है हाइबरनेट आवंटन की सीमा में मान असाइन करने का प्रयास करता है और इसलिए अनुक्रम के लिए क्वेरीिंग डेटाबेस से बचने का प्रयास करें। लेकिन अगर आप इसे 1 पर सेट करते हैं तो यह क्वेरी निष्पादित की जाएगी। इससे कोई फर्क नहीं पड़ता है क्योंकि यदि आपके डेटा बेस को किसी अन्य एप्लिकेशन द्वारा एक्सेस किया जाता है तो यह किसी अन्य एप्लिकेशन द्वारा उसी आईडी द्वारा उपयोग किए जाने पर समस्याएं पैदा करेगा।

अनुक्रम आईडी की अगली पीढ़ी आवंटन आकार पर आधारित है।

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

तो आपको SequenceGenerator का उपयोग करते समय हमेशा allocationSize=1 उपयोग करना चाहिए। जैसा कि अंतर्निहित डेटाबेस अनुक्रम के लिए हमेशा 1 बढ़ता है।





hilo