2009-10-05 13 views
7

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

create table employee (
    first_name varchar(64) not null, 
    last_name  varchar(64) not null, 
    hired_at  date, 
    department varchar(64) 
); 
create unique index emp_uidx on employee (firstname, lastname, hired_at); 

मूल डिजाइनर यह सोच कर कि डेटाबेस कंपनी के बाहर जॉन स्मिथ के बीच अंतर करने की जरूरत कभी नहीं होगा, स्थिति फ़ील्ड के रूप में hired_at स्तंभ का उपयोग करने का फैसला किया है, लेकिन वह उसी नाम वाले कर्मचारियों को उनकी hired_at तिथि से पहचाना जा सकता है। जाहिर है, यह एक प्राथमिक कुंजी बनाता है जो आंशिक रूप से शून्य और संशोधित है। चूंकि डेटाबेस इसे प्राथमिक कुंजी के रूप में अनुमति नहीं देगा, इसलिए वह इसके बजाय एक अद्वितीय अनुक्रमणिका के साथ चला गया।

अब, अगर मैं इस के लिए एक हाइबरनेट मानचित्रण लिखने की कोशिश, मैं कुछ इस तरह के साथ आ सकता है:

<hibernate-mapping> 
    <class name="com.snakeoil.personnel" table="employee"> 
    <composite-id class="com.snakeoil.personnel.EmpId" name="id"> 
     <key-property name="firstName" column="first_name" type="string"/> 
     <key-property name="lastName" column="last_name" type="string"/> 
    </composite-id> 
    <property name="hiredAt" column="hired_at" type="date"/> 
    <property name="department" type="string"> 
    </class> 
</hibernate-mapping> 

यह डेटा पढ़ने के लिए काम करता है, लेकिन जब मैं नई प्रविष्टियों में केवल अलग बनाने के उनके किराए पर लिया गया तारीख, मैं org.hibernate.NonUniqueObjectExceptions में चलाता हूं। वैकल्पिक रूप से, मैं ओरेकल की ROWID सुविधा पर विचार कर सकता हूं:

<id column="ROWID" name="id" type="string"> 
    <generator class="native"/> 
</id> 

यह डेटा पढ़ने के लिए भी ठीक काम करता है। लेकिन जाहिर है, आप नई ऑब्जेक्ट्स को जारी नहीं रख सकते हैं, क्योंकि हाइबरनेट अब एक org.hibernate.exception.SQLGrammarException फेंकता है: इकाई को स्टोर करने का प्रयास करते समय अगली अनुक्रम मान नहीं मिल सका।

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

मैं क्या देख रहा हूं? क्या हाइबरनेट को ओरेकल के रोविड के साथ सहयोग करने का कोई तरीका है, शायद एक अलग जेनरेटर के साथ? या क्या पहला विचार काम करने का कोई तरीका है, शायद चालाक डीएओ के साथ जो संस्थाओं को बेदखल और पुनः लोड करता है, और आवेदन से जटिलता को छुपाता है? या क्या मुझे शायद हाइबरनेट, इबैटिस के विकल्प की तलाश करनी चाहिए?

उत्तर

7

आप प्राथमिक कुंजी के रूप में ROWID का उपयोग नहीं करना चाहते हैं, क्योंकि यह एक पंक्ति के जीवनकाल में स्थिर होने की गारंटी नहीं है।

सिंथेटिक कुंजी जोड़ना सबसे अच्छा शर्त है। अनुक्रम मान के साथ कॉलम को पॉप्युलेट करने के लिए एक ट्रिगर का उपयोग करें।

आप विरासत पहलू पर थोड़ा अस्पष्ट हैं, इसलिए यह सुनिश्चित करना मुश्किल है कि प्रभाव क्या हैं। कॉलम जोड़ना किसी भी सम्मिलित कथन को तोड़ देगा जो स्पष्ट रूप से लक्षित कॉलम सूचीबद्ध नहीं करता है। यह किसी भी SELECT * प्रश्नों को तोड़ सकता है (जब तक वे %ROWTYPE कीवर्ड का उपयोग करके घोषित एक चर में परिवर्तित नहीं हो जाते हैं। लेकिन आपको किसी भी अन्य एप्लिकेशन को बदलने की आवश्यकता नहीं है, इसलिए मौजूदा कॉलम की बजाय नई प्राथमिक कुंजी का उपयोग किया जाता है - जब तक कि आप वास्तव में नहीं चाहते हैं।

+0

हां, ऐसा लगता है कि यह सबसे अच्छा विचार है। अन्य सभी विकल्पों में क्रुफ़्टस्टिक डीएओ जादू की आवश्यकता होती है। – wallenborn

+1

ओरेकल रोविड" स्थिर "है। केवल समस्या तब होती है जब (उद्धरण): _ अगर आप आयात और निर्यात के साथ एक पंक्ति को हटाते हैं और फिर से जोड़ते हैं उपयोगिताओं, उदाहरण के लिए, फिर इसकी पंक्ति बदल सकती है। यदि आप कोई पंक्ति हटाते हैं, तो ओरेकल अपनी पंक्ति को बाद में डाली गई एक नई पंक्ति में फिर से सौंप सकता है ._ – xmedeko

+0

@xmedeko - उद्देश्यपूर्वक उस पैराग्राफ की पहली वाक्य को छोड़ दिया गया है "आपको इसका उपयोग नहीं करना चाहिए एक तालिका की प्राथमिक कुंजी के रूप में ROWID। "Http://docs.oracle.com/cd/B19306_01/server.102/b14200/pseudocolumns008.htm – APC

5

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

बस उत्सुक - अगर सूचकांक के पहले और अंतिम नाम और किराए पर की तारीख है, तो आपकी समग्र कुंजी किराए पर लेने की तारीख क्यों नहीं रखती है? मैं सूचकांक में सभी क्षेत्रों को समग्र कुंजी में भी देखने की उम्मीद करता।

+0

यदि मैं ऐसा करता हूं, तो हाइबरनेट नल मान देता है। इसलिए, यदि कोई (स्मिथ, जॉन, 200 9 -10-01) और एक (स्मिथ, जॉन, नल) और एक (स्मिथ, जैक, नल), ए कर्मचारी से पूछताछ 'जहां अंतिम नाम =' स्मिथ 'तीन प्रविष्टियां, एक (स्मिथ, जॉन, 200 9 -10-01) और दो शून्य पॉइंटर्स लौटाएगा। यही कारण है कि मैंने शून्य क्षेत्र को एक सामान्य संपत्ति बना दिया, उम्मीद है कि मैं सक्षम हूं "इसे डीएओ में ठीक करने के लिए।" – wallenborn

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