【问题标题】:Doctrine 2 - Cannot cascade delete entities with bidirectional relations原则 2 - 不能级联删除具有双向关系的实体
【发布时间】:2014-09-02 09:19:29
【问题描述】:

尝试级联删除具有一对一和一对多双向关系的实体时,我遇到了外部约束违规。 这是我以这种方式关联的四个实体:“用户”对象可能有零个或一个“联系人”。联系人可能有零个或一个“地址”和零个或多个“电话”。但“联系人”必须与“用户”实体相关,“地址”和“电话”必须与“联系人”实体相关。

我的目标是,当我删除“用户”时,所有子对象也被级联删除(“联系人”、“地址”和“电话”)。但是,当我删除一个子对象时,我只想将其在父实体中的引用 id 设置为 NULL。

我尝试了几种方法,包括 onDelete="CASCADE" 和 onDelete=NULL 选项,但我仍然收到外部约束违规错误。

用户实体

class User
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

/**
 * Contact
 *
 * @ORM\OneToOne(targetEntity="Contact", mappedBy="user", cascade={"persist", "remove"})
 * @ORM\JoinColumn(nullable=true)
 */
private $contact;

...

}

联系实体

class Contact
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * Address
 *
 * @ORM\OneToOne(targetEntity="Address", mappedBy="contact", cascade={"persist", "remove"})
 * @ORM\JoinColumn(nullable=true)
 */
private $address;

/**
 * Telephones
 *
 * @ORM\OneToMany(targetEntity="Telephone", mappedBy="contact", cascade={"persist", "remove"})
 * @ORM\JoinColumn(nullable=true)
 */
private $telephones;

/**
 * User
 *
 * @ORM\OneToOne(targetEntity="User", inversedBy="contact", cascade={"persist"})
 * @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false)
 */
private $user;

 /**
 * Constructeur
 */
public function __construct()
{
    $this->telephones = new ArrayCollection();
}

...

}

地址实体

class Address
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @ORM\OneToOne(targetEntity="Contact",  inversedBy="address", cascade={"persist"})
 * @ORM\JoinColumn(name="contact_id", referencedColumnName="id", nullable=false)
 */
private $contact;

...

}

电话实体

class Telephone
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @ORM\ManyToOne(targetEntity="Contact", inversedBy="telephones", cascade={"persist"})
 * @ORM\JoinColumn(name="contact_id", referencedColumnName="id", nullable=false)
 */
private $contact;

...

}

【问题讨论】:

  • 到底是什么错误
  • "无法删除或更新父行:外键约束失败 (eds.eds_contact, CONSTRAINT FK_E2314CF8FB88E14F FOREIGN KEY (user_id) REFERENCES eds_user (id ))"

标签: php symfony doctrine-orm


【解决方案1】:

试试这个配置。我只是通过添加onDelete="CASCADE"@ORM\JoinColumn 注释进行了更改。这使用内置的数据库级联,因此您需要更新您的架构。 我还删除了一些无关的@ORM\JoinColumn(nullable=true) 在关系的非拥有方面的注释。这些都没有效果,只是误导。

用户实体

class User
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

/**
 * Contact
 *
 * @ORM\OneToOne(targetEntity="Contact", mappedBy="user", cascade={"persist", "remove"})
 */
private $contact;

...

}

联系实体

class Contact
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * Address
 *
 * @ORM\OneToOne(targetEntity="Address", mappedBy="contact", cascade={"persist", "remove"})
 */
private $address;

/**
 * Telephones
 *
 * @ORM\OneToMany(targetEntity="Telephone", mappedBy="contact", cascade={"persist", "remove"})
 */
private $telephones;

/**
 * User
 *
 * @ORM\OneToOne(targetEntity="User", inversedBy="contact", cascade={"persist"})
 * @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false, onDelete="CASCADE")
 */
private $user;

 /**
 * Constructeur
 */
public function __construct()
{
    $this->telephones = new ArrayCollection();
}

...

}

地址实体

class Address
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @ORM\OneToOne(targetEntity="Contact",  inversedBy="address", cascade={"persist"})
 * @ORM\JoinColumn(name="contact_id", referencedColumnName="id", nullable=false, onDelete="CASCADE")
 */
private $contact;

...

}

电话实体

class Telephone
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @ORM\ManyToOne(targetEntity="Contact", inversedBy="telephones", cascade={"persist"})
 * @ORM\JoinColumn(name="contact_id", referencedColumnName="id", nullable=false, onDelete="CASCADE")
 */
private $contact;

...

}

【讨论】:

  • 谢谢汤姆,它工作正常!我担心删除非拥有方的 JoinColumn 注释可能会删除双向关系。我错了……
【解决方案2】:
$user->setContact(null); 
$contact->setUser(null);

$em->remove($user); 
$em->remove($contact);

【讨论】:

    猜你喜欢
    • 2017-01-26
    • 1970-01-01
    • 1970-01-01
    • 2013-11-06
    • 2020-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多