Php 条令多个一对一/多对一双向完整性约束冲突

Php 条令多个一对一/多对一双向完整性约束冲突,php,orm,doctrine-orm,doctrine,symfony-2.1,Php,Orm,Doctrine Orm,Doctrine,Symfony 2.1,在最新的Symfony2学说中,试图解决两个对象之间的多重双向关系 Person owner对象在一个集合中有一个邮政地址,然后有多个辅助地址,我删除()这个人,我希望它的所有地址也被删除(但是删除地址不应该删除一个人),但是我得到了这个错误- An exception occurred while executing 'DELETE FROM address WHERE id = ?' with params {"1":"fb5e47de-2651-4069-b85e-8dbcbe8a6c4a

在最新的Symfony2学说中,试图解决两个对象之间的多重双向关系

Person owner对象在一个集合中有一个邮政地址,然后有多个辅助地址,我删除()这个人,我希望它的所有地址也被删除(但是删除地址不应该删除一个人),但是我得到了这个错误-

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`))

我想可能是因为

inversedBy="postalAddress, otherAddresses"
我认为不支持多重倒置;然后我也试着改变

@ORM\JoinColumn(nullable=false)
可以为null,但我仍然得到错误

这显然不是关于琐碎的Person/Address示例,而是更复杂的东西,但这是我在抽象方面的最佳尝试

我肯定我错过了一些明显的东西。有人能帮忙吗?

关系定义不正确 虽然您所做的可能从纯逻辑的角度来看是有意义的,但从关系数据的角度来看是没有意义的,尤其是从学说的角度来看是没有意义的

条令试图维持三种不同的关系:

  • 地址(拥有方)[双向]$person
    --多:一-->
    $otherAddresses
  • 地址(拥有方)[双向]$person
    --多:一-->
    $postalAddressperson
  • 个人(拥有方)[单向]$postalAddress
    --One:One-->
    $id地址
你看到问题了吗

使用关系标准来解决此问题。 这里的简单解决方案是使用非常常见的设计模式,即为集合设置主对象。本质上,你只需要一种关系:

  • 地址(拥有方)[双向]$person
    --多:一-->
    $otherAddresses
然后,向address添加一个属性,该属性将该地址定义为主地址。在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.
}
使用两种不同的关系,但不要跨流 如果你让一对一的关系从一个人到另一个地址是单向的,问题就会自行解决

  • 地址(拥有方)[双向]$person
    --多:一-->
    $otherAddresses
  • 个人(拥有方)[单向]$postalAddress
    --一:一-->
    地址
不过,你在这里仍然会遇到麻烦,因为如果: -主(PostalAddress)地址没有定义“多:一”的两面。(因此,您的“主”地址也必须位于
$otherAddresses
集合中)。
-尝试删除或级联删除和更新将导致这两种关系冲突,即条令的关系约束的“交叉流”,因此您必须以编程方式处理这些操作。

我认为问题可能在于您试图说多对一是由一对一而不是多对一颠倒的。您是否尝试过“*@ORM\ManyToOne(targetEntity=“Person”,inversedBy=“otherAddresses”)*@ORM\OneToOne(targetEntity=“Person”)*@ORM\JoinColumn(nullable=false)`它可能会改变条令处理级联的方式,注意:
Person::getPrimaryAddress
方法可以通过标准变得更干净。噢,天哪,我四年前问过这个问题。现在,解决方案对我来说更为明显,但当时我还不确定。谢谢你的回答!你的问题在谷歌搜索中第一次出现。虽然我认为你现在已经找到了解决问题的方法,但我想帮助下一个迷路的程序员,他在这里找到了自己的方法。
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.
}