2011-08-18 14 views
7

मेरे पास ओरेकल एक्सई 10 जी, हाइबरनेट 3.5, जेपीए 2.0 के साथ एक सेटअप है। प्राथमिक कुंजी के साथ एक साधारण तालिका है, जो प्रविष्टि पर डेटाबेस ट्रिगर द्वारा उत्पन्न होती है। ट्रिगर एक अनुक्रम से मूल्य प्राप्त करता है। ट्रिगर/अनुक्रम निर्माण ओरेकल एक्सई द्वारा किया गया था।यदि ट्रिगर द्वारा मूल्य उत्पन्न होता है तो मैं आईडी कॉलम को कैसे एनोटेट कर सकता हूं?

वास्तविक प्रश्न यह है कि: EntityManager.persist के बाद मुझे अपनी इकाई में आईडी का वर्तमान मूल्य कैसे प्राप्त हो सकता है?
मैंने कोशिश की:

@Id 
private long id; 

-> आईडी 0 है;

@Id 
@Generated(GenerationTime.ALWAYS) 
@Column(insertable = false, updatable = false) 
private long id; 

-> आईडी 0 है;

@Id 
@GeneratedValue(strategy=GenerationType.AUTO) 
private long id; 

-> विफल रहता है क्योंकि हाइबरनेट सीधे अनुक्रम (जो मौजूद नहीं है) से पूछताछ करने का प्रयास कर रहा है।

आईडी पहले दो दृष्टिकोणों में डेटाबेस में उत्पन्न होते हैं, लेकिन मेरे पास मेरे ऑब्जेक्ट में मान नहीं है।

उत्तर

2

जब तक आप ट्रिगर से बंधे न हों, यह अनुक्रम पर obfuscation के स्तर की तरह लगता है, और ऐसा लगता है कि यह सामान्य हाइबरनेट जीवन चक्र से बाहर है। क्यों सीधे अनुक्रम फोन नहीं:

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

तो फिर तुम मूल्य वापस, मिल जाएगा के रूप में हाइबरनेट सीधे उत्पादन में शामिल है, और वहाँ कुछ इस तथ्य के बाद नहीं हो रहा है।

+0

धन्यवाद, लेकिन: ट्रिगर चीज स्वचालित रूप से वृद्धिशील पीके मानों को उत्पन्न करने के लिए ओरेकल तरीका है। अगर मैं इससे छुटकारा पाता हूं, तो मैं डेटाबेस पर सीधे पूछताछ के साथ आसानी से पंक्तियों को सम्मिलित करने की संभावना खो देता हूं। और दूसरा, अगर मैं आपके सुझाव की तरह एनोटेट करता हूं, तो मैं यूनिट परीक्षणों के लिए आसानी से डर्बी पर स्विच नहीं कर सकता: (... मुझे जो चाहिए वह एक एनोटेशन है जो कहता है: "बस डीबी उत्पन्न हुआ है"। – Zeemee

+0

इस बिंदु पर गुगल किया गया, और एक कर्सर परीक्षा के आधार पर, ऐसा प्रतीत होता है कि अन्य उपयोगकर्ताओं ने हाइबरनेट से ओरेकल अनुक्रमों को दोबारा शुरू करने में सफलता प्राप्त की है। यहां एक उदाहरण है: https://forum.hibernate.org/viewtopic.php?p=2442821। डर्बी मुद्दे पर, इकाई एक डीबी मंच के खिलाफ परीक्षण जो आपके परिनियोजन प्लेटफ़ॉर्म से अलग है, एक सर्वोत्तम अभ्यास नहीं है और यूनिट परीक्षण और रनटाइम व्यवहार के बीच असंगतता का कारण बन सकता है। – atrain

+2

@Mmmmoth: जब तक कोई अन्य फ़ील्ड विशिष्ट रूप से पंक्ति की पहचान नहीं करता है, तो हाइबरनेट कैसे प्राप्त करेगा डेटाबेस से जेनरेट की गई आईडी, चूंकि अभी डाली गई पंक्ति की पहचान करने का एकमात्र तरीका इसकी आईडी है, जिसे यह नहीं पता है। संक्षेप में, आईडी प्राप्त करने के लिए आईडी की आवश्यकता है। आपका ट्रिगर वास्तव में एक बुरा विचार है –

1

आप ओरेकल सत्र के भीतर डीबी जेनरेट की गई कुंजी का आदान-प्रदान कर सकते हैं। इस के लिए, सम्मिलित करें ट्रिगर अपने कोड से

dbms_session.set_identifier(new_id) 

कॉल करना होगा, आप क्वेरी के साथ नई कुंजी मान प्राप्त कर सकता

String sql = "SELECT sys_context('USERENV', 'CLIENT_IDENTIFIER') FROM dual"; 
Query query = em.createNativeQuery(sql); 
String new_id = (String) query.getSingleResult(); 

यह नई इकाई बने के लिए एक ही EntityManager उदाहरण का उपयोग करने के लिए महत्वपूर्ण है और उत्पन्न कुंजी मान को पुनर्प्राप्त करना।

7

@ जेबी निजेट की टिप्पणियों के विपरीत, मैं वास्तव में कई कारणों के बारे में सोच सकता हूं कि हम एक ट्रिगर असाइन आईडी क्यों देंगे: संग्रहीत प्रोसेस का निष्पादन, एसक्यूएल के मैन्युअल निष्पादन और हाइबरनेट में मूल प्रश्नों को चलाने के लिए बस कुछ नाम दें।

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

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

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

एक और विकल्प ट्रिगर को संशोधित करने के लिए केवल आईडी अनुक्रम होने पर अनुक्रम अनुक्रमित करना है। "Hibernate issue with Oracle Trigger for generating id from a sequence" देखें। ज्यादातर मामलों में, यह सबसे अच्छा समाधान है क्योंकि यह स्पष्ट रूप से दिखाता है कि आईडी अनुक्रम से जुड़ा हुआ है। मेरा एकमात्र पकड़ यह है कि यह उपयोगकर्ता को पहले स्थान पर वास्तव में पूछे बिना किसी आईडी को डालने का विकल्प देता है।

+0

कृपया इस उदाहरण पर एक नज़र डालें: http://developer-should-know.com/post/82479486933/how-to-use-oracle-before-insert-trigger-for-id यह दिखाता है कि कैसे एक custome हाइबरनेट को कार्यान्वित करने के लिए जेनरेटर जो आईडी पोस्ट डालने को पुनः प्राप्त करता है। –

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

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