2015-03-21 10 views
5

में प्रत्येक कंपनी के लिए ग्राहक नम्बर जनरेटर कैसे बनाएं, मेरे पास ग्राहकों की एक तालिका है, प्रत्येक ग्राहक एक कंपनी से संबंधित है, कंपनियां चाहते हैं कि उनके ग्राहक संख्या 0 से शुरू हों और बढ़ते हों क्योंकि वे ग्राहक जोड़ते हैं और जब कंपनीबी ग्राहक जोड़ती है, कंपनी ए के ग्राहक संख्या प्रभावित नहीं होनी चाहिए। ग्राहक आईडी आंतरिक रूप से कोई भी संख्या हो सकती है, ग्राहक संख्या को कंपनी आईडी के संदर्भ में अंतर-मुक्त किया जाना चाहिए (अंतर-मुक्त के साथ मेरा मतलब 0,1,2,3,4 है, यदि 2 हटा दिया गया है, तो यह चला गया है, अगला सम्मिलन होना चाहिए 5 और नहीं 2)हाइबरनेट

Example: 
    companyId customerNumber customerId 
    0   0    0 
    0   1    1 
    0   2    2 
    0   3    3 
    0   4    4 
    0   5    5 
    1   0    6 
    1   1    7 
    1   2    8 

वहाँ कोई लेन-देन, समापन लेनदेन

खोलने अधिकतम CUSTOMERNUMBER खोजने, अधिकतम +1 CUSTOMERNUMBER के रूप में उपयोग करते हुए एक प्रवेश डालने और से यह करने के लिए एक बेहतर तरीका है कि अगर मैं सोच रहा था क्या कोई ऐसी एनोटेशन है जिसका मैं उपयोग कर सकता हूं जहां मैं ग्राहक संख्या उत्पन्न करने के लिए मानदंड निर्दिष्ट कर सकता हूं? अगली ग्राहक संख्या उस कंपनी के भीतर उपलब्ध उच्चतम संख्या होनी चाहिए। (मेरे पास लगभग 20 अन्य संस्थाएं हैं जिनकी तारीख और comapnyId के आधार पर समान मानव-पठनीय-वृद्धिशील-आईडी आवश्यकताएं हैं और मैं ग्राहक को संख्या-प्रकार की फ़ील्ड पीढ़ी को जितना संभव हो सके मूर्ख-सबूत के रूप में बनाना चाहता हूं, मुझे याद रखना नहीं है यह हर ऐसा करने के लिए मैं एक नई इकाई जारी रहती है)

कुछ की तरह:

@SequenceGenerator(uniqueOver="companyId,customerNumber",strategy=GenerationType.AUTO) 
private Long customerNumber; 

समाधान के बाद से मैं स्टॉक और वित्तीय डेटा के साथ काम कर रहा हूँ एसिड अनुरूप होना चाहिए।

अद्यतन: मैंने ग्राहक को आईडी और ग्राहक के नाम पर बदल दिया है ग्राहक को भ्रम को रोकने के लिए।

अद्यतन: जब मैं खाई से मुक्त मतलब है, मेरा मतलब है कि customerNumbers 0,1,2,3,4,5,6,7,8,9 होना चाहिए - अगर मैं 4 नंबर को हटाना यह चला गया है हमेशा के लिए और अगले डालने 10 होना चाहिए जब तक कि मैं एक नई कंपनी बनाने के लिए, उसके बाद अपना पहला ग्राहक पर 0.

अद्यतन शुरू कर देना चाहिए: मैं हाइबरनेट साथ वसंत का उपयोग कर रहा है, तो @PrePersist एनोटेशन के लिए काम नहीं कर रहा मुझे। @PrePersist एक समाधान के रूप का सुझाव दिया है, तो यह वसंत के तहत काम करने की जरूरत है, तो साइमन के प्रश्न के लिए एक जवाब की जरूरत होगी: Enable @PrePersist and @PreUpdate in Spring

सुझाए गए जवाब जो मैं के बारे में निश्चित नहीं हूँ:

@Entity 
@Table(name = "Customer") 
public class Customer { 

    @Table(name = "CustomerNumber") 
    @Entity(name = "sequenceIdentifier") 
    public static class CustomerNumberSequenceIdentifier { 

     @Id 
     @GenericGenerator(name = "sequence", strategy = "sequence", parameters = { 
       @org.hibernate.annotations.Parameter(name = "sequenceName", value = "sequence"), 
       @org.hibernate.annotations.Parameter(name = "allocationSize", value = "1"), 
     }) 
     @GeneratedValue(generator = "sequence", strategy=GenerationType.SEQUENCE) 
     private Long id; 

    } 


    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long customerId; 

    @ManyToOne 
    private Company company; 

    @GeneratedValue(generator = "sequenceIdentifier", strategy=GenerationType.TABLE) 
    private Long customerNumber 

} 

उत्तर

1

आप हाइबरनेट का उपयोग कर company_d भर में एक अद्वितीय बाधा डाल; उदाहरण क्वेरी

Query query = session.createQuery("insert into customer (company_id, customer_id)" +"(select :company_id, IFNULL(max(customer_id),1)+1 from customer where company_id = :company_id)");

//set the company_id here 

    int result = query.executeUpdate(); 

नोट: IFNULL ने MySQL विशिष्ट वाक्यविन्यास

मैं एक अलग कंपनी मास्टर तालिका में कंपनी आईडी auto_increment क्षेत्र रखने की सलाह देते हैं है।

2

मैं चीजों (खेद) की हाइबरनेट ओर से बात नहीं कर सकते हैं, तो आप इस एक मेज के साथ mysql में इतने लंबे समय के रूप में यह MyISAM इंजन का उपयोग करता निम्न तालिका संरचना के साथ पूरा कर सकते हैं,:

create table ai_test (
    company_id integer, 
    customer_number integer auto_increment, 
    primary key (company_id, customer_number) 
) engine=MyISAM; 

यहाँ वायुसेना है idd दिखा रहा है कि कार्रवाई में: http://sqlfiddle.com/#!9/45e78/1

क्षमा करें मैं इसे आपके लिए हाइबरनेट करने के लिए अनुवाद नहीं कर सकता - कभी इसका उपयोग नहीं किया, लेकिन यह एक प्रारंभिक बिंदु हो सकता है।

संपादित
के बाद से Inno की आवश्यकता है, तो आप इस मेज और ट्रिगर इस्तेमाल कर सकते हैं:

create table ai_test (
    company_id integer, 
    customer_number integer, 
    primary key (company_id, customer_number) 
) engine=InnoDB; 


create trigger inno_composite_ai_ok before insert on ai_test 
for each row 
begin 
    set new.customer_number =  
     (select ifnull((select max(customer_number)+1 
         from ai_test 
          where 
         company_id=new.company_id),1)); 
end// 

यहाँ आप के लिए एक नमूना बेला है: http://sqlfiddle.com/#!9/fffd0/14

संपादित
एक और सिंगल कॉलम पीके

की आवश्यकता को शामिल करने के लिए अपडेट करें
create table ai_test (
    company_id integer, 
    customer_no integer, 
    customer_id integer primary key auto_increment 

) engine=InnoDB; 

create trigger inno_composite_ai_ok before insert on ai_test 
for each row 
begin 
    set new.customer_no =  
     (select ifnull((select max(customer_no)+1 
         from ai_test 
          where 
         company_id=new.company_id),1)); 
end// 

fiddle here

नोट आप कर सकते हैं (और शायद चाहिए)/CUSTOMER_NO

1

आप प्रत्येक तालिका के लिए एक नया अनुक्रम संख्या उत्पन्न करने के लिए डीडीएल लिखने के बिना अनुक्रम संख्या पीढ़ी की तलाश में हैं। इसे एक अलग अनुक्रम संख्या तालिका के साथ करें और सम्मिलित करने के लिए दोनों तालिकाओं को लॉक करने के लिए अद्यतन लेनदेन के लिए एक चयन बनाएं। हाइबरनेट इसे बढ़ाए गए टेबल के साथ करता है। http://vladmihalcea.com/hibernate-identity-sequence-and-table-sequence-generator/

टेबल (SEQUENCE) अनुभाग, जो अनुक्रम संख्या समाधान की एक तालिका है करने के लिए नीचे स्क्रॉल:

यहाँ एक बहुत अच्छा उदाहरण है।

उदाहरण में केवल सही नाम प्राप्त करने के लिए ग्राहक नाम को अनुक्रम नाम के रूप में निर्दिष्ट करें।

ओवरहेड हर नई कंपनी के लिए अनुक्रम पंक्ति उत्पन्न कर रहा है, और प्रत्येक नए ग्राहक के लिए टेबल लॉक कर रहा है।

+0

आपकी टेबलसेक्वेंसइडिएंटियर क्लास, मुझे लगता है कि, मेरे मामले में, ग्राहक वर्ग होगा? टेबल अनुक्रम उदाहरण का उपयोग करके मैं प्रति कंपनी ग्राहक संख्या कैसे प्राप्त करूं? –

+0

तालिका अनुक्रम पहचानकर्ता वर्ग एक अलग तालिका है जो केवल आपके ग्राहकों के लिए अनुक्रम मान संग्रहीत करती है। यह कंपनी के लिए कंपनी और अगले अनुक्रम मूल्य रखेगा। हाइबरनेट आपके सम्मिलित लेनदेन को लपेटने के लिए अद्यतन/अद्यतन रणनीति के चयन के लिए उन्नत तालिकाओं प्रदान करता है। यह आपको एक लॉक सुरक्षित अनुक्रम अद्यतन देता है। आपकी ग्राहक तालिका सम्मिलन अब टेबल अनुक्रम पहचानकर्ता वर्ग पर भरोसा करेगी। – user1442498

+0

मैं काफी कुछ नहीं कर रहा हूं ... मैंने अपना प्रश्न अपडेट कर लिया है, ग्राहक आईडी एक ऑटो-इंक्रिमेंटिंग फील्ड है, प्रत्येक कंपनी के पास कई ग्राहक हो सकते हैं और प्रत्येक ग्राहक संख्या प्रति कंपनी बढ़ाना चाहिए। क्या मेरा ग्राहक नम्बरसेक्वेंसइडिएंफायर क्लास सही है जो मैं करने की कोशिश कर रहा हूं और मैं इसे ग्राहक नम्बर में कैसे ला सकता हूं ताकि मैं ग्राहक संख्या प्राप्त कर सकूं जो उपरोक्त मेरे उदाहरण के अनुसार प्रति कंपनी बढ़ती है? जिन उदाहरणों को मैं ढूंढ रहा हूं वे सभी दिखा रहे हैं कि अनुक्रम संख्या तालिका अनुक्रम उत्पन्न कर रही है। मेरे प्रश्न में हाइबरनेट मॉडल को संपादित करने और अंतराल को भरने के लिए स्वतंत्र महसूस करें। –