在尝试级联删除具有一对一和一对多双向关系的实体时,我遇到了外部约束违规。 以下是我这四种相关的实体:“用户”对象可能有零个或一个“联系人”。联系人可能有零或一个“地址”和零或多个“电话”。但“联系”必须与“用户”实体相关,以及“地址”和“电话”与“联系”实体相关。
我的目标是,当我删除“用户”时,所有子对象也被级联删除(“联系人”,“地址”和“电话”)。但是,当我删除子对象时,我只想将父实体中的引用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;
...
}
答案 0 :(得分:1)
$user->setContact(null);
$contact->setUser(null);
$em->remove($user);
$em->remove($contact);
答案 1 :(得分:1)
尝试此配置。我只是通过添加@ORM\JoinColumn
对onDelete="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;
...
}