2013-01-10 21 views
12

सबसे पहले, मेरी गरीब अंग्रेजी के लिए खेद है ...(doctrine2 + symfony2) व्यापक निकालें: अखंडता बाधा उल्लंघन 1451

मैं चार संस्थाओं मिला: उपयोगकर्ता, आवेदन, बंडल & इकाई। यहाँ उनके संबंधों हैं (व्यापक जारी रहती है & निकालना, नीचे दिए गए कोड देखें):

  • उपयोगकर्ता 1-एन आवेदन
  • आवेदन 1-एन बंडल
  • बंडल 1-एन इकाई

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

तो मैं एक 1-1 संबंध के साथ उपयोगकर्ता दो क्षेत्रों, ENTITY1 & ENTITY2 पर जोड़ने के लिए,। और अब मेरी ऐप्लिकेशन क्रैश:

An exception occurred while executing 'DELETE FROM bundle WHERE id = ?' with params {"1":13}: 

SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`misc`.`entity`, CONSTRAINT `FK_E284468F1FAD9D3` FOREIGN KEY (`bundle_id`) REFERENCES `bundle` (`id`)) 

मैं this post में स्थापित किया उन सहित कई चीज़ें करने की कोशिश की, लेकिन मैं इसे ठीक करने के लिए सक्षम नहीं था।

किसी भी मदद का स्वागत है, अग्रिम धन्यवाद।

संपादित करें: उपयोगकर्ता की ENTITY1 & ENTITY2 अशक्त हो सकता है: मैं करते रहे कि उपयोगकर्ता-> इकाई संबंधों optionnal हैं की जरूरत है। त्रुटि तब भी होती है जब वे दोनों शून्य हों।

# User : 
    /** 
    * @ORM\OneToMany(targetEntity="\sfCommands\ContentBundle\Entity\Application", mappedBy="user", cascade={"remove"}, orphanRemoval=true) 
    * @ORM\OrderBy({"name" = "ASC"}) 
    */ 
    protected $applications; 

    /** 
    * @ORM\OneToOne(targetEntity="\sfCommands\ContentBundle\Entity\Entity") 
    * @ORM\JoinColumn(name="entity1_id", referencedColumnName="id") 
    */ 
    private $entity1; 

    /** 
    * @ORM\OneToOne(targetEntity="\sfCommands\ContentBundle\Entity\Entity") 
    * @ORM\JoinColumn(name="entity2_id", referencedColumnName="id") 
    */ 
    private $entity2; 

#Application : 
    /** 
    * @ORM\OneToMany(targetEntity="\sfCommands\ContentBundle\Entity\Bundle", mappedBy="application", cascade={"remove"}, orphanRemoval=true) 
    * @ORM\OrderBy({"name" = "ASC"}) 
    */ 
    protected $bundles; 

    /** 
    * @ORM\ManyToOne(targetEntity="\sfCommands\UserBundle\Entity\User", inversedBy="applications", cascade={"persist"}) 
    * @ORM\JoinColumn(name="user_id", referencedColumnName="id") 
    */ 
    protected $user; 

#Bundle : 
    /** 
    * @ORM\ManyToOne(targetEntity="\sfCommands\ContentBundle\Entity\Application", inversedBy="bundles", cascade={"persist"}) 
    * @ORM\JoinColumn(name="application_id", referencedColumnName="id") 
    */ 
    protected $application; 

    /** 
    * @ORM\OneToMany(targetEntity="\sfCommands\ContentBundle\Entity\Entity", mappedBy="bundle", cascade={"remove"}, orphanRemoval=true) 
    * @ORM\OrderBy({"name" = "ASC"}) 
    */ 
    protected $entitys; 

#Entity : 
    /** 
    * @ORM\ManyToOne(targetEntity="\sfCommands\ContentBundle\Entity\Bundle", inversedBy="entitys", cascade={"persist"}) 
    * @ORM\JoinColumn(name="bundle_id", referencedColumnName="id") 
    */ 
    protected $bundle; 
+0

कोई मौका द्वारा किया bundle_id आप निकालना संस्थाओं युग्मित है की कोशिश की यह किसी भी उपयोगकर्ता क्षेत्र में एक इकाई भी थी? (entity1_id या entity2_id) – Pankrates

+0

बंडल के बच्चे (इकाई) उपयोगकर्ता फ़ील्ड (entity1_id या entity2_id) में नहीं हैं, भले ही विफल हो जाएं। कैस्केडिंग की तरह लगता है बिल्कुल काम नहीं कर रहा है। – bgaze

उत्तर

31

तो, that french forum करने के लिए धन्यवाद, मैं समस्या तय:

यहाँ मेरी संस्थाओं परिभाषाएं दी गई हैं।

मैं जोड़ने के लिए की जरूरत नल = सच & onDelete = "सेट शून्य" @ORM \ JoinColumn में

यहाँ व्यावहारिक विन्यास है, हो सकता है यह आपकी मदद करेगा किसी को:

#User. 
    /** 
    * @ORM\OneToMany(targetEntity="\sfCommands\ContentBundle\Entity\Application", mappedBy="user", cascade={"remove"}, orphanRemoval=true) 
    * @ORM\OrderBy({"name" = "ASC"}) 
    */ 
    protected $applications; 

    /** 
    * @ORM\OneToOne(targetEntity="\sfCommands\ContentBundle\Entity\Entity") 
    * @ORM\JoinColumn(name="entity1_id", referencedColumnName="id", nullable=true, onDelete="SET NULL") 
    */ 
    private $entity1; 

    /** 
    * @ORM\OneToOne(targetEntity="\sfCommands\ContentBundle\Entity\Entity") 
    * @ORM\JoinColumn(name="entity2_id", referencedColumnName="id", nullable=true, onDelete="SET NULL") 
    */ 
    private $entity2; 

#Application. 
    /** 
    * @ORM\OneToMany(targetEntity="\sfCommands\ContentBundle\Entity\Bundle", mappedBy="application", cascade={"remove"}, orphanRemoval=true) 
    * @ORM\OrderBy({"name" = "ASC"}) 
    */ 
    protected $bundles; 

    /** 
    * @ORM\ManyToOne(targetEntity="\sfCommands\UserBundle\Entity\User", inversedBy="applications", cascade={"persist"}) 
    * @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true, onDelete="SET NULL") 
    */ 
    protected $user; 

#Bundle. 
    /** 
    * @ORM\ManyToOne(targetEntity="\sfCommands\ContentBundle\Entity\Application", inversedBy="bundles", cascade={"persist"}) 
    * @ORM\JoinColumn(name="application_id", referencedColumnName="id", nullable=true, onDelete="SET NULL") 
    */ 
    protected $application; 

    /** 
    * @ORM\OneToMany(targetEntity="\sfCommands\ContentBundle\Entity\Entity", mappedBy="bundle", cascade={"remove"}, orphanRemoval=true) 
    * @ORM\OrderBy({"name" = "ASC"}) 
    */ 
    protected $entitys; 

#Entity. 
    /** 
    * @ORM\ManyToOne(targetEntity="\sfCommands\ContentBundle\Entity\Bundle", inversedBy="entitys", cascade={"persist"}) 
    * @ORM\JoinColumn(name="bundle_id", referencedColumnName="id", nullable=true, onDelete="SET NULL") 
    */ 
    protected $bundle; 
+0

मैं आपको सलाम करता हूं, महोदय! – Nevertheless

+0

मुझे घंटे बचाया! धन्यवाद! – Albeis

3

onDelete = "CASCADE" भी ठीक काम करता है। लेकिन ऐप/कंसोल सिद्धांत चलाने के लिए मत भूलना: स्कीमा: अद्यतन - बल डीबी स्तर के परिवर्तन से पहले प्रभावी होगा।

+1

nullable = true और onDelete = "SET NULL" संयोजन मेरे मामले में केवल उपयोगकर्ताओं को हटाने की अनुमति है, न कि उनके आरक्षण, जो आरक्षण तालिका में अनाथ रिकॉर्ड का कारण बनते हैं। यहां तक ​​कि उपयोगकर्ता इकाई में OneToMany संबंध पर कैस्केड = {"निकालें"} + orphanRemoval = true को सेट करने में भी मदद नहीं मिली। इसलिए, मेरी सलाह है कि डेल्टे = "कैस्केड" पर उपयोग करना है, यह ट्रिगर उपयोगकर्ता रिकॉर्ड के साथ-साथ किसी भी समस्या के बिना संबंधित आरक्षण को हटा देता है – basejumper

+0

लेकिन यदि आप संदर्भ को हटाते हैं, तो उपयोगकर्ता नहीं, पर डिलीट ट्रिगर नहीं होता है। मेरे मामले में, मैं कमजोर इकाई के एफके में एक पूर्ण के साथ समाप्त होता हूं। यह शून्य नहीं माना जाता है। – juanmf

0

अनाथ रिमूवल कुछ बार काम नहीं करता है क्योंकि यह PersistencCollection पर निर्भर करता है (इसमें शेड्यूल हो जाता है)। और हम ArrayCollection#removeElement() पर कॉल कर रहे हैं।

बाद PersistencCollection#remove()

if ($this->association !== null && 
     $this->association['type'] & ClassMetadata::TO_MANY && 
     $this->owner && 
     $this->association['orphanRemoval']) { 
     $this->em->getUnitOfWork()->scheduleOrphanRemoval($removed); 
    } 

का एक टुकड़ा है और ArrayCollection कि नहीं करता है।

18

उपयोग onDelete = "CASCADE" आप एनोटेशन उपयोग कर रहे हैं

/** 
* @ORM\ManyToOne(targetEntity="Report", inversedBy="responses") 
* @ORM\JoinColumn(name="reportId", referencedColumnName="id",onDelete="CASCADE") 
*/ 

उपयोग onDelete: CASCADE यदि आप उपयोग कर रहे हैं YML

joinColumn: 
     name: pid 
     referencedColumnName: id 
     onDelete: CASCADE 
+0

यह मेरे लिए उपयोगी था। मैं इस तरह के मुद्दे का सामना कर रहा था और तय हो गया .. धन्यवाद –

+0

बहुत बढ़िया! – kabrice

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