2012-07-10 15 views
5

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

उदा .:

$log = new Log(); 
$log->setTypeId(1); 
$log->setUserId(1); 
$entityManager->persist($log); 
$entityManager->flush(); 

ऊपर मैं त्रुटि मिलेगा जिसमें बताया गया अगर मैं कोड का प्रयास करें: वफ़ादारी बाधा उल्लंघन: 1048 स्तंभ 'user_id' अशक्त नहीं हो सकता। और मैं पहले प्रकार वस्तु और डी उपयोगकर्ता वस्तु बनाने के लिए है और उन्हें पारित:

$log->setType($TypeObject) 
$log->setUser($UserObject) 

लेकिन दूसरी इकाई वस्तुओं के लिए मैं मूल्य सीधे बताए कोई समस्या नहीं है, यही कारण है कि है?

यह मेरा इकाई लॉग है:

<?php 
/** 
* @Entity 
* @Table(name="log") 
* @HasLifecycleCallbacks 
*/ 
class Log 
{ 
    /** 
    * @var type 
    * @Id 
    * @Column(type="integer") 
    * @GeneratedValue 
    */ 
    protected $id; 

    /** 
    * 
    * @var type 
    * @Column(type="integer") 
    */ 
    protected $user_id; 

    /** 
    * 
    * @var type 
    * @Column(type="integer") 
    */ 
    protected $type_id; 

    /** 
    * 
    * @var type 
    * @Column(type="datetime") 
    */ 
    protected $created; 

    /** 
    * 
    * @var type 
    * @ManyToOne(targetEntity="User", inversedBy="logs") 
    */ 
    protected $user; 

    /** 
    * 
    * @ManyToOne(targetEntity="Type", inversedBy="logs") 
    */ 
    protected $type; 

    public function getId() 
    { 
     return $this->id; 
    } 

    public function getUserId() 
    { 
     return $this->user_id; 
    } 

    public function getTypeId() 
    { 
     return $this->type_id; 
    } 

    public function getCreated() 
    { 
     return $this->created; 
    } 

    public function setUserId($userId) 
    { 
     $this->user_id = $userId; 
    } 

    public function setTypeId($typeId) 
    { 
     $this->type_id = $typeId; 
    } 

    public function setCreated($created) 
    { 
     $this->created = $created; 
    } 

    public function setUser($user) 
    { 
     $this->user = $user; 
    } 

    public function setType($type) 
    { 
     $this->type = $type; 
    } 

    /** 
    * @PrePersist 
    */ 
    public function prePersist() 
    { 
     $this->setCreated(new DateTime()); 
    } 

} 
?> 
+1

खुशी हुई जिसने मदद की। यह मुझे 1 के निशान में भेज दिया। वू हू। –

उत्तर

4

संपादित

मैं Doctrine2 की वेबसाइट पर इस बयान पाया। यह एक बेहतरीन प्रथा है कि आप अपने मॉडल को कोडिंग करते समय पालन करना चाहेंगे।

Doctrine2 Best Practices

25,9। किसी इकाई में फ़ील्ड में विदेशी कुंजी को मानचित्र न करें

विदेशी कुंजी का कोई ऑब्जेक्ट मॉडल में कोई अर्थ नहीं है। विदेशी कुंजी यह है कि कैसे एक रिलेशनल डेटाबेस संबंध स्थापित करता है। आपका ऑब्जेक्ट मॉडल ऑब्जेक्ट संदर्भों के माध्यम से संबंध स्थापित करता है। इस प्रकार विदेशी कुंजी मानचित्रण आपत्ति उठाने क्षेत्रों भारी ऑब्जेक्ट मॉडल में संबंधपरक मॉडल का ब्यौरा लीक, कुछ तुम सच में ऐसा नहीं करना चाहिए

संपादित

सिद्धांत अपने-अपने आईडी करने के लिए अपने वस्तुओं से मानचित्रण करता है।

आपने जो किया है वह थोड़ा अनावश्यक है।

आपने अनिवार्य रूप से दो बार एक ही सिद्धांत को बताया है।

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

आप बस निम्नलिखित बजाय

<?php 
/** 
* @Entity 
* @Table(name="log") 
* @HasLifecycleCallbacks 
*/ 
class Log 
{ 
    /** 
    * @var type 
    * @Id 
    * @Column(type="integer") 
    * @GeneratedValue 
    */ 
    protected $id; 

    /** 
    * 
    * @var type 
    * @Column(type="datetime") 
    */ 
    protected $created; 

    /** 
    * 
    * @var type 
    * @ManyToOne(targetEntity="User", inversedBy="logs") 
    */ 
    protected $user; 

    /** 
    * 
    * @ManyToOne(targetEntity="Type", inversedBy="logs") 
    */ 
    protected $type; 

    public function getId() 
    { 
     return $this->id; 
    } 

    public function getCreated() 
    { 
     return $this->created; 
    } 

    public function setCreated($created) 
    { 
     $this->created = $created; 
    } 

    public function setUser($user) 
    { 
     $this->user = $user; 
    } 

    public function setType($type) 
    { 
     $this->type = $type; 
    } 

    /** 
    * @PrePersist 
    */ 
    public function prePersist() 
    { 
     $this->setCreated(new DateTime()); 
    } 

} 

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

यदि आपके पास एक आईडी है, क्योंकि आप आगे के अंत में उपयोग कर रहे हैं, तो केवल Entitymanager का उपयोग करके उस आईडी से जुड़े ऑब्जेक्ट को प्राप्त करें।

$user = $em->getEntity('User', $idFromWeb); 
$log = new Log(); 
$log->setUser($user); 
+1

डीबी से $ उपयोगकर्ता को पुनर्प्राप्त करना एक ओवरहेड की तरह लगता है। अगर लॉग एंट्री केवल उपयोगकर्ता आईडी की आवश्यकता है, तो आपको पूरे उपयोगकर्ता रिकॉर्ड को क्यों पुनर्प्राप्त करना चाहिए। क्या इससे बचने का कोई तरीका है? –

+0

मुबिक्स, आप सही हैं। लेकिन इस अनुरोध के दौरान आप शायद अपनी प्राथमिकताओं को प्राप्त करने या पासवर्ड की जानकारी या अन्य चीजों को सत्यापित करने के लिए पहले ही उपयोगकर्ता इकाई को ला चुके हैं। Doctrine2 भी एक बार कभी इकाई को लाता है। यदि आप GetEntity को कई बार कॉल करते हैं तो Doctrine2 डेटाबेस पर वापस जाने के बिना उसी ऑब्जेक्ट को वापस रखेगा। –

+1

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

20

मौजूदा उत्तर कभी मेरे साथ अच्छा नहीं रहा।ऐसे कई वैध परिदृश्य हैं जहां किसी ऑब्जेक्ट को केवल रिश्ते को परिभाषित करने के लिए लोड करना है, जबकि पहले ही एफके आसान है, बस कोई समझ नहीं आता है।

एक बेहतर समाधान है सिद्धांत की EntityManager की getRefrence विधि का उपयोग करना।

Reference Proxies...

विधि EntityManager # getReference ($ EntityName, $ पहचानकर्ता) आप लोड हो रहा है डेटाबेस से उस संस्था के बिना एक इकाई है, जिसके लिए पहचानकर्ता जाना जाता है, के लिए एक संदर्भ प्राप्त करने देता है। यह उपयोगी है, उदाहरण के लिए, एक प्रदर्शन वृद्धि के रूप में, जब आप किसी संस्था के साथ एसोसिएशन स्थापित करना चाहते हैं जिसके लिए आपके पास पहचानकर्ता है। आप बस ऐसा कर सकता है:

<?php 
    // $em instanceof EntityManager, $cart instanceof MyProject\Model\Cart 
    // $itemId comes from somewhere, probably a request parameter 
    $item = $em->getReference(\MyProject\Model\Item::class, $itemId); 
    $cart->addItem($item); 

हो सकता है कि यह जब यह सवाल पहले पोस्ट किया गया उपलब्ध नहीं था - मैं नहीं जानता।

+3

मुझे इस विधि के बारे में पता नहीं था और ऐसा लगता है कि मूल पोस्टर क्या मांग रहा है। –

+0

यह सही है। क्या यह एक नई सुविधा है? – pagliuca

+0

मैंने यह निर्धारित करने की कोशिश की कि यह उपलब्ध होने पर निश्चित नहीं है (2.0>?)। पिछले साल जोड़ा गया था। – ficuscr

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