gin*_*nja 7 php orm doctrine doctrine-orm symfony-2.1
在Sytrfony2的最新Doctrine试图找出两个对象之间的多个双向关系.
Person owner对象有一个邮政地址,然后是一个集合中的多个辅助地址,我删除了()Person,我希望它的所有地址也被删除(但删除地址不应该删除一个人),但我是得到这个错误 -
An exception occurred while executing 'DELETE FROM address WHERE id = ?' with
params {"1":"fb5e47de-2651-4069-b85e-8dbcbe8a6c4a"}:
[PDOException] SQLSTATE[23000]: Integrity constraint violation: 1451
Cannot delete or update a parent row: a foreign key constraint fails
(`db`.`address`, CONSTRAINT `FK_633704 C29C1004E`
FOREIGN KEY (`person_id`) REFERENCES `person` (`id`))
Run Code Online (Sandbox Code Playgroud)
在
class Person
{
/**
* @var Address postalAddress
*
* @ORM\OneToOne(targetEntity="Address", cascade={"all"}, orphanRemoval=true)
* @ORM\JoinColumn(onDelete="cascade")
*/
private $postalAddress;
/**
* @var \Doctrine\Common\Collections\Collection otherAddresses
*
* @ORM\OneToMany(targetEntity="Address", mappedBy="person", cascade={"all"}, orphanRemoval=true)
*/
private $otherAddresses;
}
class Address
{
/**
* @var Person person
*
* @ORM\ManyToOne(targetEntity="Person", inversedBy="postalAddress, otherAddresses")
* @ORM\JoinColumn(nullable=false)
*/
private $person;
}
Run Code Online (Sandbox Code Playgroud)
我以为可能是因为
inversedBy="postalAddress, otherAddresses"
Run Code Online (Sandbox Code Playgroud)
我不认为支持多个inversedBy; 然后我也试着改变
@ORM\JoinColumn(nullable=false)
Run Code Online (Sandbox Code Playgroud)
可以为空,但我仍然得到错误.
这显然不是关于琐碎的Person/Address示例,而是更复杂的东西,但这是我最好的抽象尝试.
我敢肯定我错过了一些明显的东西.有人可以帮忙吗?
虽然从纯粹逻辑的角度来看,您所做的事情可能有意义,但从关系数据的角度来看却没有意义,特别是从 Doctrine 的角度来看没有意义。
Doctrine 试图维持 3 种不同的关系:
--Many:One-->$otherAddresses Person--Many:One-->$postalAddress Person--One:One-->$id地址你看到问题了吗?
这里的简单解决方案是使用非常常见的设计模式,为集合设置主值。本质上,您只需要一种关系:
--Many:One-->$otherAddresses Person然后,添加一个属性来定义该地址为主地址。在 Person 和 Address 实体中以编程方式处理此问题:
Class Person
{
. . .
public function getPrimaryAddress() {
if (null === $this->primaryAddress) {
foreach($this->getOtherAddresses() as $address) {
if ($address->isPrimary()) {
$this->primaryAddress = $address;
break;
}
}
}
return $this->primaryAddress;
}
// similar for the setter, update the old address as not primary if there is one, set the new one as primary.
}
Run Code Online (Sandbox Code Playgroud)
如果您保持从“人”到“地址”的单向一对一关系,问题就会自行解决。
--Many:One-->$otherAddresses Person--One:One--> 地址不过,您仍然会遇到麻烦,因为 Doctrine 会在以下情况下抱怨: - 主(PostalAddress)地址没有定义Many:One的两侧。(因此您的“主要”地址也必须在$otherAddresses集合中)。- 尝试删除或级联删除和更新将导致这两种关系发生冲突,“交叉流”学说的关系约束,因此您必须以编程方式处理这些操作。
| 归档时间: |
|
| 查看次数: |
1400 次 |
| 最近记录: |