15

首先,对不起我的英语不好...

我有四个实体:用户、应用程序、捆绑和实体。这是它们的关系(具有级联持久性和删除,请参见下面的代码):

  • 用户1-n应用程序
  • 应用程序1-n
  • 捆绑1-n实体

它工作正常。但是一个用户可以默认拥有他的两个实体,我需要直接访问它们。

所以我在用户上添加了两个字段,entity1 和 entity2,具有1-1的关系。现在我的应用程序崩溃了:

An exception occurred while executing 'DELETE FROM bundle WHERE id = ?' with params {"1":13}:

SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`misc`.`entity`, CONSTRAINT `FK_E284468F1FAD9D3` FOREIGN KEY (`bundle_id`) REFERENCES `bundle` (`id`))

我尝试了几件事,包括在这篇文章中创建的那些,但我无法修复它。

欢迎任何帮助,在此先感谢。

编辑:我需要指出 User->Entity 关系是可选的:用户的 entity1 和 entity2 可以为空。即使它们都为空,也会发生错误。

这是我的实体定义:

# User :
    /**
     * @ORM\OneToMany(targetEntity="\sfCommands\ContentBundle\Entity\Application", mappedBy="user", cascade={"remove"}, orphanRemoval=true)
     * @ORM\OrderBy({"name" = "ASC"})
     */
    protected $applications;

    /**
     * @ORM\OneToOne(targetEntity="\sfCommands\ContentBundle\Entity\Entity")
     * @ORM\JoinColumn(name="entity1_id", referencedColumnName="id")
     */
    private $entity1;

    /**
     * @ORM\OneToOne(targetEntity="\sfCommands\ContentBundle\Entity\Entity")
     * @ORM\JoinColumn(name="entity2_id", referencedColumnName="id")
     */
    private $entity2;

#Application :
    /**
     * @ORM\OneToMany(targetEntity="\sfCommands\ContentBundle\Entity\Bundle", mappedBy="application", cascade={"remove"}, orphanRemoval=true)
     * @ORM\OrderBy({"name" = "ASC"})
     */
    protected $bundles;

    /**
     * @ORM\ManyToOne(targetEntity="\sfCommands\UserBundle\Entity\User", inversedBy="applications", cascade={"persist"})
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    protected $user;

#Bundle :
    /**
     * @ORM\ManyToOne(targetEntity="\sfCommands\ContentBundle\Entity\Application", inversedBy="bundles", cascade={"persist"})
     * @ORM\JoinColumn(name="application_id", referencedColumnName="id")
     */
    protected $application;

    /**
     * @ORM\OneToMany(targetEntity="\sfCommands\ContentBundle\Entity\Entity", mappedBy="bundle", cascade={"remove"}, orphanRemoval=true)
     * @ORM\OrderBy({"name" = "ASC"})
     */
    protected $entitys;

#Entity :
    /**
     * @ORM\ManyToOne(targetEntity="\sfCommands\ContentBundle\Entity\Bundle", inversedBy="entitys", cascade={"persist"})
     * @ORM\JoinColumn(name="bundle_id", referencedColumnName="id")
     */
    protected $bundle;
4

4 回答 4

39

所以,感谢这个法语论坛,我解决了这个问题。

我需要在 @ORM\JoinColumn添加nullable=true & onDelete="SET NULL"

这是可行的配置,也许它会帮助某人:

#User.
    /**
     * @ORM\OneToMany(targetEntity="\sfCommands\ContentBundle\Entity\Application", mappedBy="user", cascade={"remove"}, orphanRemoval=true)
     * @ORM\OrderBy({"name" = "ASC"})
     */
    protected $applications;

    /**
     * @ORM\OneToOne(targetEntity="\sfCommands\ContentBundle\Entity\Entity")
     * @ORM\JoinColumn(name="entity1_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
     */
    private $entity1;

    /**
     * @ORM\OneToOne(targetEntity="\sfCommands\ContentBundle\Entity\Entity")
     * @ORM\JoinColumn(name="entity2_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
     */
    private $entity2;

#Application.
    /**
     * @ORM\OneToMany(targetEntity="\sfCommands\ContentBundle\Entity\Bundle", mappedBy="application", cascade={"remove"}, orphanRemoval=true)
     * @ORM\OrderBy({"name" = "ASC"})
     */
    protected $bundles;

    /**
     * @ORM\ManyToOne(targetEntity="\sfCommands\UserBundle\Entity\User", inversedBy="applications", cascade={"persist"})
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
     */
    protected $user;

#Bundle.
    /**
     * @ORM\ManyToOne(targetEntity="\sfCommands\ContentBundle\Entity\Application", inversedBy="bundles", cascade={"persist"})
     * @ORM\JoinColumn(name="application_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
     */
    protected $application;

    /**
     * @ORM\OneToMany(targetEntity="\sfCommands\ContentBundle\Entity\Entity", mappedBy="bundle", cascade={"remove"}, orphanRemoval=true)
     * @ORM\OrderBy({"name" = "ASC"})
     */
    protected $entitys;

#Entity.
    /**
     * @ORM\ManyToOne(targetEntity="\sfCommands\ContentBundle\Entity\Bundle", inversedBy="entitys", cascade={"persist"})
     * @ORM\JoinColumn(name="bundle_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
     */
    protected $bundle;
于 2013-01-14T04:13:43.370 回答
23

如果您使用注释,请使用 onDelete="CASCADE"

/**
 * @ORM\ManyToOne(targetEntity="Report", inversedBy="responses")
 * @ORM\JoinColumn(name="reportId", referencedColumnName="id",onDelete="CASCADE")
 */

如果您使用的是 yml,请使用 onDelete: CASCADE

joinColumn:
      name: pid
      referencedColumnName: id
      onDelete: CASCADE
于 2015-03-11T04:58:56.640 回答
3

onDelete="CASCADE" 也可以正常工作。但是不要忘记在数据库级别更改生效之前运行 app/console 学说:模式:更新 --force。

于 2013-11-12T09:55:46.907 回答
1

orphanRemoval 有时不起作用,因为它取决于 (被安排在) PersistencCollection。我们可能会打电话给ArrayCollection#removeElement().

以下是部分截图PersistencCollection#remove()

    if ($this->association !== null &&
        $this->association['type'] & ClassMetadata::TO_MANY &&
        $this->owner &&
        $this->association['orphanRemoval']) {
        $this->em->getUnitOfWork()->scheduleOrphanRemoval($removed);
    }

而 ArrayCollection 不这样做。

于 2014-07-15T20:56:42.777 回答