学说2 - 不能级联删除具有双向关系的实体

时间:2014-09-02 09:19:30

标签: php symfony doctrine-orm

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

我的目标是,当我删除“用户”时,所有子对象也被级联删除(“联系人”,“地址”和“电话”)。但是,当我删除子对象时,我只想将父实体中的引用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;

...

}

2 个答案:

答案 0 :(得分:1)

$user->setContact(null); 
$contact->setUser(null);

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

答案 1 :(得分:1)

尝试此配置。我只是通过添加@ORM\JoinColumnonDelete="CASCADE"注释进行了更改。这使用内置数据库级联,因此您需要更新架构。 我还在关系的非拥有方面删除了一些无关的@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;

...

}