2011-11-03 19 views
7

से आईडी उत्पन्न करने के लिए ओरेकल ट्रिगर के साथ हाइबरनेट समस्या हमारे पास पहले से सम्मिलित ट्रिगर है जो अनुक्रम से अगला मान प्राप्त करता है। जब ऑब्जेक्ट को सेव() विधि के साथ रखा जाता है, तो हाइबरनेट अनुक्रम से मान प्राप्त करता है और इसे ऑब्जेक्ट में जोड़ता है। और जब लेन-देन स्प्रिंग की सेवा परत से किया जाता है, तो आईडी मान को डेटाबेस पर फिर से बढ़ाया जाता है। कैसे .. मैं nextval हो रही() अगर वस्तु पहले से ही एक आईडी है से बचने करना ..अनुक्रम

यहाँ मैं क्या करने की कोशिश कर रहा मा क्या है

UserDao

public User saveUser(User user){ 
     session.getCurrentSession.save(user);//line2 
     return user;//line3 
} 

UserService

public void saveUserAndWriteToAudit(User user, UserAudit userAudit){ 
    userDao.saveUser(user);//line1 
    userAudit.setUserId(user.getId);//line4 
    userAudit.saveUserAudit(userAudit);//line5 
} 

और उपयोगकर्ता क्लास

@Entity 
    public class User{ 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO, generator="a1") 
    @SequenceGenerator(name="a1", sequenceName="usersequence") 
    private Long id; 
    ///////////////// 
} 

जब कर्सर लाइन 1 तक पहुंचता है और लाइन 2 उपयोगकर्ता ऑब्जेक्ट आईडी विशेषता में शून्य है। लाइन 2 के बाद, यह अनुक्रम से अगला है - कहें 1. लाइन 4 पर, मैंने उपयोगकर्ता की आईडी = 1 को उपयोगकर्ता को ऑब्जेक्ट करने के लिए जोड़ा है .. जब लेन-देन लाइन 5 के बाद किया जाता है, 2 उपयोगकर्ता के आईडी कॉलम में और 1 उपयोगकर्ता उपयोगकर्ता के उपयोगकर्ता आईडी कॉलम में डाला जाता है। यह मेरे लिए :(कोई उद्देश्य में कार्य करता है कि मैं इस मुद्दे से कैसे बच सकता हूँ? धन्यवाद!

उत्तर

9

आईडी को नहीं दिए जाने पर बस अपने ट्रिगर को केवल आग पर अपडेट करें।

create or replace 
trigger sa.my_trigger 
before insert on sa.my_table 
for each row 
when (new.id is null) 
begin 
    select sa.my_sequence.nextval 
    into :new.id 
    from dual; 
end; 
+0

धन्यवाद मैथ्यू .. – RKodakandla

0

आदर्श रूप में आप सम्मिलित करें TRIGGER से पहले हटा। आप नहीं करते हैं, हाइबरनेट प्राथमिक कुंजी जानने का कोई तरीका नहीं है, और यह वास्तव में जरूरत है उस जानकारी। यदि आपको INSERT के बाद ऑब्जेक्ट की परवाह नहीं है जो ठीक हो सकता है (दूसरा स्तर कैश अभी भी एक मुद्दा है), लेकिन अगर आपको इसे तुरंत उपयोग करने की आवश्यकता है तो यह एक वास्तविक समस्या है। बाद के मामले में, आप कर सकते थे इस बुरा तरीके का प्रयास करें:।

  1. बताएँ हाइबरनेट कि आप प्राथमिक कुंजी का प्रबंधन खुद
  2. नई वस्तु बना सकते हैं और प्राथमिक कुंजी में एक मनमाना मूल्य डाल
  3. अपने हाइबरनेट सत्र को फ़्लश करें और अनुक्रम चुनें। CURRVAL (माना जाता है कि केवल एक ही INSERT है)।
  4. प्राप्त वर्तमान अनुक्रम मूल्य का उपयोग कर ऑब्जेक्ट लोड करें और उपर्युक्त उदाहरण का उपयोग न करें।
+0

@ फ़ेलिक्सएम .. उत्तर के लिए धन्यवाद .. अगर हम ट्रिगर को संशोधित करने के लिए संशोधित करते हैं: new.id = null या नहीं, क्या यह काम करेगा? .. मैं इसका परीक्षण नहीं कर सकता क्योंकि मेरे पास ट्रिगर को संशोधित करने के लिए डीबी विशेषाधिकार नहीं हैं .. मुझे यह सुनिश्चित करने की ज़रूरत है कि इसे डीबीए को संशोधित करने से पहले पर्याप्त – RKodakandla

+0

यदि आप अन्य प्रतिक्रिया में वर्णित ट्रिगर को संशोधित करते हैं, तो आप अनुक्रम का उपयोग करने के लिए हाइबरनेट को बता सकते हैं। – FelixM

5

उपरोक्त समाधान बहुत अच्छा है, इसने मुझे इस समस्या पर बहुत सारे सिरदर्द बचाए हैं।

मेरा एकमात्र पकड़ यह है कि यह वास्तव में अनुक्रम की जांच किए बिना किसी भी आईडी मान को सम्मिलित करने के लिए उपयोगकर्ता/कोड का द्वार खोलता है।

मुझे पता चला है कि निम्न समाधान भी काम करता है। यह हाइबरनेट को अधिकतम आईडी ढूंढने देता है और प्रत्येक बार एक सम्मिलित कथन निष्पादित होने पर इसे बढ़ाया जाता है। लेकिन जब यह डेटाबेस हिट, आईडी नजरअंदाज कर दिया है और ट्रिगर द्वारा उत्पन्न से परिवर्तित कर दिया है, तो वहाँ कोई uniqueness in a cluster problem है:

@Id 
    @GeneratedValue(generator="increment") 
    @GenericGenerator(name="increment", strategy = "increment") 
    private Long id; 

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

+0

धन्यवाद क्रिस्टोफर, मैं प्राथमिक कुंजी को पॉप्युलेट करने के लिए डेटाबेस ट्रिगर का उपयोग करने के लिए संघर्ष कर रहा था और इस मुद्दे को हल किया। – user75ponic

0
create or replace 
trigger sa.my_trigger 
before insert on sa.my_table 
for each row 
when (new.id is null) 
begin 
    select sa.my_sequence.nextval 
    into :new.id 
    from dual; 
end; 

यह डेटाबेस दुनिया से वास्तव में कुछ गलत है।

समाधान के ऊपर विचार करते हुए, sa.my_sequence.nextval 51 है और आपका हाइबरनेट फ्रेमवर्क बिना किसी समस्या के काम करेगा। लेकिन अगर कोई आपके प्राथमिक कुंजी मान के साथ सीधा जेडीबीसी डालने देता है तो अनुक्रम को ओवरराइड करने के लिए 66 कहें (कहें, 52 के रूप में वर्तमान मान), ट्रिगर बस डालेगा।

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

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