2012-09-26 8 views
14

के लिए भेदभावकर्ता अपडेट करें इन कक्षाओं के साथ, आप "कर्मचारी" के लिए "व्यक्ति" के लिए रिकॉर्ड कैसे बदलेंगे।सिद्धांत: SINGLE_TABLE विरासत

/** 
* @Entity 
* @InheritanceType("SINGLE_TABLE") 
* @DiscriminatorColumn(name="discr", type="string") 
* @DiscriminatorMap({"person" = "Person", "employee" = "Employee"}) 
*/ 
class Person 
{ 
    // ... 
} 

/** 
* @Entity 
*/ 
class Employee extends Person 
{ 
    // ... 
} 

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

क्या मुझे कस्टम एसक्यूएल क्वेरी लिखने की ज़रूरत है या क्या मैं कुछ और कर रहा हूं जो मौलिक रूप से गलत है?

उत्तर

32

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

  1. एक उपवर्ग अधिक विशेषताओं को परिभाषित करने और यह निर्माता में कुछ additionnal काम कर सकता:

    सबसे पहले, मैं आपको बता दूँ कारण है कि यह एक बुरा विचार कर रही है। क्या हमें फिर से नया कन्स्ट्रक्टर चलाया जाना चाहिए? क्या यह हमारे पुराने ऑब्जेक्ट के कुछ विशेषताओं को ओवरराइट करता है?

  2. क्या होगा यदि आप उस कोड के किसी हिस्से में उस व्यक्ति के उदाहरण पर काम कर रहे थे, और फिर यह अचानक एक कर्मचारी में बदल जाता है (जिसमें कुछ परिभाषित व्यवहार हो सकता है जिसे आप उम्मीद नहीं करेंगे) ?!

यही कारण है कि अधिकांश भाषाएं आपको निष्पादन के दौरान किसी वास्तविक वस्तु के वास्तविक वर्ग प्रकार को बदलने की अनुमति नहीं देगी (और स्मृति, ज़ाहिर है, लेकिन मैं विवरण में शामिल नहीं होना चाहता)। कुछ आपको ऐसा करने देते हैं (कभी-कभी मुड़ने वाले तरीकों से, जैसे कि जेवीएम), लेकिन यह वास्तव में अच्छा अभ्यास नहीं है!

अधिकांशतः, ऐसा करने की आवश्यकता खराब ऑब्जेक्ट उन्मुख डिजाइन निर्णयों में निहित है।

उन कारणों से, सिद्धांत आपको अपनी इकाई वस्तु के प्रकार को बदलने की अनुमति नहीं देगा। बेशक, आप बदलाव को करने के लिए सादे एसक्यूएल (लेकिन इस के माध्यम से पढ़ सकते हैं!) लिख सकते हैं, लेकिन यहां दो "साफ" विकल्प हैं जो मैं सुझाव दूंगा:

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

  1. जब भी आप, Employee को Person से "प्रकार बदल" कर्मचारी का एक नया उदाहरण बना सकते हैं और डेटा आप पुराने व्यक्ति वस्तु से कर्मचारी ऑब्जेक्ट के लिए खत्म हो प्रतिलिपि बनाना चाहते हैं कॉपी करना होगा। पुरानी इकाई को हटाने और नए बने रहने के लिए मत भूलना।
  2. विरासत की बजाय संरचना का उपयोग करें (अन्य लेखों के विवरण और लिंक के लिए यह wiki article देखें)। संपादित करें: इसके नरक के लिए, here's a part of a nice conversation with Erich Gamma "विरासत पर संरचना" के बारे में!

संबंधित चर्चा here और here देखें।


अब, यहाँ सादे एसक्यूएल विधि के बारे में मैं पहले बात कर रहा था है - मुझे आशा है कि आप इसका इस्तेमाल की जरूरत नहीं होगी!

सुनिश्चित करें कि आपकी क्वेरी स्वीकृत है (क्योंकि क्वेरी बिना किसी सत्यापन के निष्पादित की जाएगी)।

/** 
* Execute an SQL statement and return the number of affected rows. 
* 
* @param string $statement 
* @return integer The number of affected rows. 
*/ 
public function exec($statement) 
{ 
    $this->connect(); 
    return $this->_conn->exec($statement); 
} 
+1

आपको बहुत बहुत धन्यवाद:

$query = "UPDATE TABLE_NAME_HERE SET discr = 'employee' WHERE id = ".$entity->getId(); $entity_manager->getConnection()->exec($query); 

यहाँ प्रलेखन और कार्यकारी तरीका है जिसके DBAL\Connection कक्षा में है (आपकी जानकारी के लिए) के लिए कोड है। शेष सहज; मैं आपकी सलाह लेगा और सादे एसक्यूएल से बचूंगा। – Nate

+0

इस पर दो बार ठोकर खाई और वास्तव में मेरी मदद की। धन्यवाद! – Strategist

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