如何在Docrine 2中彻底删除关系?

时间:2017-10-22 12:49:00

标签: doctrine-orm doctrine persistence cascade

有实体EndpointEndpointServerConfigServer

enter image description here

/**
 * Server
 *
 * @ORM\Table(
 *     name="server",
 *     indexes={
 *         @ORM\Index(name="fk_server_server_type_idx", columns={"server_type_id"}),
 *         @ORM\Index(name="fk_server_cluster_idx", columns={"cluster_id"})
 *     }
 * )
 * @ORM\Entity
 */
class Server
{
    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=32, nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     *
     * @Groups({"export"})
     */
    protected $name;

    /**
     * @var EndpointServerConfig[]
     */
    protected $endpointServerConfigs;
}

/**
 * EndpointServerConfig
 *
 * @ORM\Table(name="endpoint_server_config", indexes={
 *     @ORM\Index(name="fk_endpoint_server_config_server_idx", columns={"server_name"})}
 * )
 * @ORM\Entity
 */
class EndpointServerConfig
{

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    protected $id;

    /**
     * @var Server
     *
     * @ORM\ManyToOne(targetEntity="Server")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="server_name", referencedColumnName="name")
     * })
     *
     * @Groups({"export"})
     */
    protected $server;

    /**
     * @var Endpoint
     *
     * @ORM\OneToOne(targetEntity="Endpoint", mappedBy="endpointServerConfig")
     */
    protected $endpoint;
}

/**
 * Endpoint
 *
 * @ORM\Table(
 *     name="endpoint",
 *     indexes={
 *         ...
 *         @ORM\Index(name="fk_endpoint_endpoint_server_config_idx", columns={"endpoint_server_config_id"}),
 *         ...
 *     }
 * )
 * @ORM\Entity
 * ...
 */
class Endpoint
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    protected $id;
}

现在我想要更新包含Foo的实体(例如Endpoint)。在其他更改中,我想从Server的{​​{1}}中删除对Endpoint的引用。这意味着对于数据库:EndpointServerConfig需要设置为endpoint_server_config.server

我将NULL加载到Foo,禁用服务器并提交更改。在服务器端,我取消Zend\Form超过EndpointServerConfig#server

Foo

导致错误:

/** @var Foo $myFoo */
if(! $myFoo->getEndpoint()->getEndpointServerConfig()->getServer() || ! $myFoo->getEndpoint()->getEndpointServerConfig()->getServer()->getName()) {
    $myFoo->getEndpoint()->getEndpointServerConfig()->setServer(null);
}
$this->entityManager->persist($myFoo);
$this->entityManager->flush($myFoo);

这意味着,Doctrine会尝试An exception occurred while executing 'UPDATE server SET name = ? WHERE name = ?' with params ["", "someservername"]: SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`mydb`.`endpoint_server_config`, CONSTRAINT `fk_endpoint_server_config_server` FOREIGN KEY (`server_name`) REFERENCES `server` (`name`) ON DELETE NO ACTION ON UPDATE NO ACTION) UPDATE,而不是仅仅从Server删除对它的引用。但为什么呢?

只有当我手动将EndpointServerConfig设置为endpoint_server_config.server_name(直接在数据库中)时,我才能通过表单和Doctrine保存更改。

如何让它发挥作用?

修改

注意到,我在NULL的每次更新时遇到同样的问题。因此,当我尝试设置新的EndpointServerConfig时,不仅在setServer(null)上也是如此。在这种情况下,尝试会导致错误:

Server

1 个答案:

答案 0 :(得分:0)

添加以下内容: -

 cascade={"persist", "remove"} 

关于你的关系。

 @ORM\ManyToOne(targetEntity="Server", cascade={"persist", "remove"})