2010-04-07 17 views
33

मैं जेपीए सीख रहा हूं और @SequenceGenerator एनोटेशन में भ्रम है।जावा - जेपीए - जेनरेटर - @ सिकेंस जेनरेटर

मेरी समझ के लिए, यह स्वचालित रूप से किसी इकाई के संख्यात्मक पहचान फ़ील्ड/गुणों के लिए मान निर्दिष्ट करता है।

प्रश्न 1। क्या यह अनुक्रम जनरेटर डाटाबेस के बढ़ते संख्यात्मक मूल्य उत्पन्न करने की क्षमता का उपयोग करता है या संख्या को स्वयं बनाता है?

प्रश्न 2। यदि जेपीए डेटाबेस ऑटो वृद्धि सुविधा का उपयोग करता है, तो क्या यह डेटास्टोर के साथ काम करेगा जिसमें ऑटो वृद्धि सुविधा नहीं है?

क्यू 3। यदि जेपीए अपने आप पर संख्यात्मक मूल्य उत्पन्न करता है, तो जेपीए कार्यान्वयन कैसे पता चलता है कि कौन सा मूल्य अगली उत्पन्न करेगा? क्या यह मानने के लिए पहले डेटाबेस से परामर्श करता है कि मूल्य (अंतिम + 1) उत्पन्न करने के लिए आखिर में कौन सा मूल्य संग्रहीत किया गया था?


क्यू 4। कृपया sequenceName और allocationSize @SequenceGenerator एनोटेशन के गुणों पर कुछ प्रकाश डालें।

उत्तर

47

sequenceName डीबी में अनुक्रम का नाम है। इस प्रकार आप एक अनुक्रम निर्दिष्ट करते हैं जो डीबी में पहले से मौजूद है। यदि आप इस मार्ग पर जाते हैं, तो आपको allocationSize निर्दिष्ट करना होगा, जिसे डीबी अनुक्रम अपने "ऑटो वृद्धि" के रूप में उपयोग करता है।

उपयोग:

@GeneratedValue(generator="my_seq") 
@SequenceGenerator(name="my_seq",sequenceName="MY_SEQ", allocationSize=1) 

यदि आप चाहते हैं, आप यह आप के लिए एक दृश्य बना सकते हैं कर सकते हैं। लेकिन ऐसा करने के लिए, आपको इसे बनाने के लिए स्कीमाजनेशन का उपयोग करना होगा। ऐसा करने के लिए, का उपयोग करें:

@GeneratedValue(strategy=GenerationType.SEQUENCE) 

इसके अलावा, आप स्वत: पीढ़ी है, जो एक तालिका का उपयोग आईडी जेनरेट करने के लिए होगा का उपयोग कर सकते हैं। इस सुविधा का उपयोग करते समय आपको किसी बिंदु पर स्कीमाजनेशन का भी उपयोग करना चाहिए, इसलिए जनरेटर तालिका बनाई जा सकती है। ऐसा करने के लिए, उपयोग करें:

@GeneratedValue(strategy=GenerationType.AUTO) 
+3

जेपीए प्रदाता (उदाहरण के लिए हाइबरनेट) आधार के रूप में अनुक्रम मान का उपयोग करेगा, और * आवंटित * ​​इसे आवंटित आकार के साथ वास्तविक आईडी प्राप्त करने के लिए आकार देगा। तो यदि अगला सीईसी मूल्य 11 है और आवंटन आकार 20 है, तो अगली आईडी जेनरेट की जाएगी 220. आमतौर पर, आप बस अपनी आईडी को अनुक्रम मूल्य का पालन करना चाहते हैं, इसलिए आवंटन सेट = अनुक्रम के द्वारा वृद्धि सेट करें। यह भी देखें http://stackoverflow.com/questions/5346147/hibernate-oracle-sequence-produces-large-gap –

+0

यह गैर-आईडी कॉलम के लिए काम नहीं करता है। –

2

मेरे पास ऑटोजन मानों के साथ MySQL स्कीमा है। मैं strategy=GenerationType.IDENTITY टैग का उपयोग करता हूं और ऐसा लगता है कि MySQL में ठीक काम करता है, मुझे लगता है कि इसे अधिकांश डीबी इंजन भी काम करना चाहिए।

CREATE TABLE user (
    id bigint NOT NULL auto_increment, 
    name varchar(64) NOT NULL default '', 
    PRIMARY KEY (id) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

User.java:

// mark this JavaBean to be JPA scoped class 
@Entity 
@Table(name="user") 
public class User { 
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private long id; // primary key (autogen surrogate) 

    @Column(name="name") 
    private String name; 

    public long getId() { return id; } 
    public void setId(long id) { this.id = id; } 

    public String getName() { return name; } 
    public void setName(String name) { this.name=name; } 
} 
9

मैं इस का उपयोग करें और यह काम करता है सही

@Id 
@GeneratedValue(generator = "SEC_ODON", strategy = GenerationType.SEQUENCE) 
@SequenceGenerator(name = "SEC_ODON", sequenceName = "SO.SEC_ODON",allocationSize=1) 
@Column(name="ID_ODON", unique=true, nullable=false, precision=10, scale=0) 
public Long getIdOdon() { 
    return this.idOdon; 
} 
3

हालांकि इस सवाल का बहुत पुराना है और मैं जेपीए के साथ अपने खुद के मुद्दों के लिए इस पर ठोकर खाई 2.0 और ओरेकल अनुक्रम।

चीजों में से कुछ पर अपना शोध साझा करना चाहते हैं -

रिश्ता (allocationSize) की GenerationType के बीच @SequenceGenerator।SEQUENCE और डेटाबेस अनुक्रम परिभाषा वेतन वृद्धि द्वारा

यकीन @SequenceGenerator (allocationSize) डाटाबेस अनुक्रम परिभाषा द्वारा वेतन वृद्धि समस्याओं से बचने के रूप में एक ही मूल्य पर सेट है। उदाहरण के लिए । यदि हम 20 के मूल्य के साथ डेटाबेस में अनुक्रम को परिभाषित करते हैं, तो अनुक्रम जेनरेटर में आवंटन को 20 तक सेट करें। इस मामले में जेपीए डेटाबेस तक कॉल नहीं करेगा जब तक कि यह अगले 20 अंक तक पहुंच न जाए, जबकि यह प्रत्येक मान को 1 से बढ़ाता है आंतरिक रूप से। यह प्रत्येक बार अगली अनुक्रम संख्या प्राप्त करने के लिए डेटाबेस कॉल सहेजता है। इसका दुष्प्रभाव है - जब भी एप्लिकेशन को पुन: नियोजित किया जाता है या सर्वर को बीच में पुनरारंभ किया जाता है, तो यह अगले बैच प्राप्त करने के लिए डेटाबेस को कॉल करेगा और आपको अनुक्रम मानों में कूद दिखाई देगा। इसके अलावा हमें यह सुनिश्चित करने की ज़रूरत है कि डेटाबेस परिभाषा और एप्लिकेशन सेटिंग इन-सिंक हो, जो हर समय संभव नहीं हो सकती क्योंकि दोनों अलग-अलग समूहों द्वारा प्रबंधित की जाती हैं और आप तुरंत नियंत्रण खो सकते हैं। यदि डेटाबेस मान आवंटन से कम है, तो आपको आईडी के डुप्लिकेट मानों के कारण प्राथमिक कुंजी बाधा त्रुटियां दिखाई देगी। यदि डेटाबेस मान आवंटन से अधिक है, तो आप आईडी के मानों में कूद देखेंगे।

यदि डेटाबेस अनुक्रम वृद्धि 1 पर सेट है (जो आमतौर पर डीबीए करता है), आवंटन आकार को 1 के रूप में सेट करें ताकि वे इन-सिंक हो जाएं लेकिन जेपीए प्रत्येक बार अगली अनुक्रम संख्या प्राप्त करने के लिए डेटाबेस को कॉल करता है।

यदि आप हर बार डेटाबेस को कॉल नहीं करना चाहते हैं, तो जेनरेशन टाइप टाइप करें रणनीति का उपयोग करें और डेटाबेस ट्रिगर द्वारा @Id मान सेट करें। GenerationType.IDENTITY जैसे ही हम वस्तु डीबी में सहेजा जाता है और इसलिए हम एक em.merge या उन्हें ऐसा करने की जरूरत नहीं है आईडी के लिए एक मान दिया वस्तु को सौंपा गया है फोन em.persist के साथ .flush। (यह हो सकता है जेपीए प्रदाता यकीन specific..Not)

एक अन्य महत्वपूर्ण बात -

जेपीए 2.0 स्वचालित रूप से ALTER SEQUENCE डेटाबेस अनुक्रम में allocationSize और वृद्धि से सिंक करने के लिए आदेश चलाता है। ज्यादातर के रूप में हम एक अलग स्कीमा नाम (अनुप्रयोग उपयोगकर्ता नाम) के बजाय वास्तविक स्कीमा जहां अनुक्रम मौजूद है और उपयोगकर्ता अनुप्रयोग नाम ALTER SEQUENCE विशेषाधिकार नहीं होगा का उपयोग करें, आप लॉग में नीचे चेतावनी दिखाई दे सकती -

000004 सी 1 रनटाइम डब्ल्यू सीडब्ल्यूडब्ल्यूजेपी 99 9 1 डब्ल्यू: ओपनजेपीए। रनटाइम: चेतावनी: अनुक्रम "RECORD_ID_SEQ" अनुक्रम के लिए अनुक्रम मान कैश करने के लिए अक्षम। आपके एप्लिकेशन को एक वैकल्पिक SEQUENCE आदेश चलाने की अनुमति नहीं है। सुनिश्चित करें कि इसके पास एक वैकल्पिक SEQUENCE आदेश चलाने के लिए उचित अनुमति है।

रूप जेपीए अनुक्रम को बदल नहीं सकता है, जेपीए डेटाबेस हर कॉल अगले क्रम संख्या @ SequenceGenerator.allocationSize का मूल्य की परवाह किए बिना प्राप्त करने के लिए। यह एक अवांछित परिणाम हो सकता है जिसे हमें अवगत होना चाहिए।

जेपीए को यह आदेश चलाने के लिए नहीं जाने के लिए, इस मान को - persistence.xml में सेट करें। यह सुनिश्चित करता है कि जेपीए वैकल्पिक SEQUENCE आदेश चलाने की कोशिश नहीं करेगा। हालांकि यह एक अलग चेतावनी लिखते हैं -

00000094 क्रम डब्ल्यू CWWJP9991W: openjpa.Runtime: चेतावनी: संपत्ति "openjpa.jdbc।DBDictionary = disableAlterSeqenceIncrementBy " सही पर सेट किया है। इसका मतलब है कि 'परिवर्तन SEQUENCE ... वृद्धि से' एसक्यूएल बयान दृश्य के लिए क्रियान्वित किया जा नहीं होगा" RECORD_ID_SEQ "। OpenJPA इस आदेश निष्पादित करता है सुनिश्चित करने के लिए है कि मूल्य द्वारा इस सीक्वेंस के वेतन वृद्धि डेटाबेस में परिभाषित allocationSize जो में इकाई के अनुक्रम परिभाषित किया गया है से मेल खाता है। यह SQL विवरण अक्षम के साथ, यह उपयोगकर्ता की जिम्मेदारी जिससे कंपनी के अनुक्रम परिभाषा अनुक्रम डेटाबेस में परिभाषित से मेल खाता सुनिश्चित करने के लिए है।

जैसा कि चेतावनी में उल्लेख किया गया है, यहां महत्वपूर्ण है कि हमें यह सुनिश्चित करने की आवश्यकता है कि @SequenceGener ator.allocation डेटाबेस अनुक्रम परिभाषा में आकार और वृद्धि @ सिकेंस जेनरेटर (आवंटन आकार) के डिफ़ॉल्ट मान सहित 50 में है। अन्यथा यह त्रुटियों का कारण बन जाएगा।

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