16

嗨,我有以下课程

namespace MP\User\RegistrationBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Persistence\PersistentObject;
use MP\Services\SiteAdapterBundle\Util\String;
/**
 * @ORM\Table(name="customer")
 * @ORM\Entity(repositoryClass="MP\User\RegistrationBundle\Repositories\CustomerRepository")
 * @ORM\HasLifecycleCallbacks
 */
class Customer extends PersistentObject
{
    
    /**
     * @var string $id
     * @ORM\Id
     * @ORM\Column(name="icustomer_id", type="integer")
     */
    protected $id;

    /**
     * @var string $addresses
     * @ORM\OneToMany(targetEntity="MP\User\RegistrationBundle\Entity\Address", mappedBy="customer", cascade={"remove"})
     */
    protected $addresses;

有以下关系

/**
 * MP\User\RegistrationBundle\Entity
 */
namespace MP\User\RegistrationBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Persistence\PersistentObject;

/**
 * @ORM\Table(name="custdeladd") 
 * @ORM\Entity(repositoryClass="MP\User\RegistrationBundle\Repositories\AddressRepository")
 */
class Address extends PersistentObject
{
      /**
       * @var integer $suffix
       * @ORM\Column(name="isuffix", type="integer") 
       * @ORM\Id
       */
      protected $suffix;

      /**
       * @var object $customer
       * @ORM\ManyToOne(targetEntity="MP\User\RegistrationBundle\Entity\Customer", inversedBy="addresses", cascade={"persist"})
       * @ORM\JoinColumn(name="icustomer_id", referencedColumnName="icustomer_id")
       */
      protected $customer;
}

有谁知道为什么当客户被删除时地址不是?非常感谢

4

3 回答 3

43

您的关系定义似乎很好。删除客户的方式是什么?我的意思是 Doctrine 没有直接在数据库中设置“ON DELETE CASCADE”。因此,如果您以“教义”以外的其他方式删除客户实体,评论将不会被删除。

您可以通过添加注释告诉教义直接在数据库中设置它:

@ORM\JoinColumn(name="icustomer_id", referencedColumnName="icustomer_id", onDelete="CASCADE")

但是,如果您尝试以正确的方式删除实体,这仍然不起作用,请尝试将“orphanRemoval”添加为true,它应该会有所帮助:

// Customer.php
/**
 * @var string $addresses
 * @ORM\OneToMany(targetEntity="MP\User\RegistrationBundle\Entity\Address", mappedBy="customer", cascade={"remove"}, orphanRemoval=true)
 */
protected $addresses;
于 2012-10-16T09:37:14.657 回答
12

我在让它工作时遇到了很多麻烦。以下几点可能会对遇到类似问题的人有所帮助:

  1. 拥有实体需要@OneToMany( ... cascade={"remove"}cascade={"all"} )
  2. 子实体也需要@JoinColumn(... onDelete="CASCADE")
  3. 此外,如果您正在修改该onDelete="CASCADE"部分,我相信您需要在更改生效之前更新您的架构。
于 2015-03-10T23:32:58.847 回答
0

我尝试了上面的答案,但得到了相同的外键约束违规。

我的代码如下所示:

class FooBar
{
    /**
     * @ORM\OneToMany(
     *     targetEntity="Foo",
     *     mappedBy="foobar",
     *     cascade={"persist", "remove"},
     *     orphanRemoval=true
     * )
     * @var Collection|Foo[]
     */
    private $fooCollection;

    /**
     * @return Collection|Foo[]
     */
    public function getFooCollection()
    {
        return $this->fooCollection;
    }

    /**
     * @param Collection|Foo[] $fooCollection
     *
     * @return $this
     */
    public function setFooCollection($fooCollection): FooBar
    {
        $this->fooCollection = $fooCollection;
        return $this;
    }
}

class Foo
{
    // ... some more properties & ID here ....

    /**
     * @ORM\OneToMany(
     *     targetEntity="Bar",
     *     mappedBy="foo",
     *     cascade={"persist", "remove"},
     *     orphanRemoval=true
     * )
     * @var Collection|Bar[]
     */
    private $barCollection;

    /**
     * @ORM\ManyToOne(
     *     targetEntity="FooBar",
     *     inversedBy="fooCollection"
     * )
     * @ORM\JoinColumn(
     *     name="fooBarId",
     *     referencedColumnName="fooBarId",
     *     nullable=false
     * )
     * @var FooBar
     */
    private $fooBar;

    public function __construct()
    {
        $this->barCollection = new ArrayCollection();
    }

    /**
     * @return Bar[]|Collection
     */
    public function getBarCollection()
    {
        return $this->barCollection;
    }

    /**
     * @param Bar[]|Collection $barCollection
     *
     * @return $this
     */
    public function setBarCollection($barCollection): Foo
    {
        $this->barCollection = $barCollection;
        return $this;
    }

    /**
     * @return FooBar
     */
    public function getFooBar(): FooBar
    {
        return $this->fooBar;
    }

    /**
     * @param FooBar $fooBar
     *
     * @return $this
     */
    public function setFooBar(FooBar $fooBar): Foo
    {
        $this->fooBar = $fooBar;
        return $this;
    }

    // ... some more getters & setters here ...
}

class Bar
{
    // ... some more properties & ID here ....

    /**
     * @ORM\ManyToOne(
     *     targetEntity="Foo",
     *     inversedBy="barCollection"
     * )
     * @ORM\JoinColumn(
     *     name="fooId",
     *     referencedColumnName="fooId",
     *     nullable=false
     * )
     * @var Foo
     */
    private $foo;

    // ... some more getters & setters here ...
}

我有程序的另一部分,我尝试使用以下代码删除与 FooBar 对应的所有 Foo。

$fooBar = new FooBar();
$fooBar->setFooCollection([]);

$entityManager->persist($foorBar);
$entityManager->flush();

这给出了 Foo 和 Bar 之间关系的外键异常“无法删除或更新父行:外键约束失败”。

将以下方法添加到 FooBar:

/**
     * @param Foo[] $collection
     */
    public function removeFooCollection($collection)
    {
        /** @var Foo $entry */
        foreach ($collection as $entry)
        {
            $this->fooCollection->removeElement($entry);
            $entry->setFooBar(null);
        }
    }

并使用以下代码删除与 FooBar 相关的所有 Foo:

$fooBar->removeFooCollection(
     $fooBar->getFooCollection()
);
$entityManager->persist($fooBar);
$entityManager->flush();

修复了所有外键约束问题。

于 2019-05-09T12:14:59.540 回答