在 Doctrine2 中,不能删除单向多对一关系(不能设置为空)
In Doctrine2, cannot remove unidirectional many-to-one relation (cannot set to null)
我有一个像用户实体一样工作的身份验证实体,以及一个具有与身份验证实体单向相关的 属性 的国家/地区实体:
/**
* @var Authentication
*
* @ORM\ManyToOne(targetEntity="Authentication")
* @ORM\JoinColumn(name="`archived_by`", referencedColumnName="id")
*/
private $archivedBy;
/**
* @param Authentication $archivedBy
* @return Country
*/
public function setArchivedBy(Authentication $archivedBy = null)
{
$this->archivedBy = $archivedBy;
return $this;
}
至于文档,连接列默认可为空。
当我想在侦听器中将用户设置为这个 archivedBy 属性 时,它按预期工作:
public function preRemove(LifecycleEventArgs $event)
{
$entity = $event->getObject();
$entity->setArchivedBy($this->tokenStorage->getToken()->getUser());
$om = $event->getObjectManager();
$om->persist($entity);
$om->flush();
}
但是当我想在它的控制器中将这个 属性 设置为空(想删除关系)时,它没有按预期工作:
$country->setArchivedBy(null);
在 Symfony 分析器的 Doctrine2 调试中,我看到 sql 查询不包括 "SET archived_by = null",这样:
UPDATE "country" SET "archived_at" = NULL, "updated_by" = '80fa198a-3216-46cd-aedb-64ce7ff27801', "updated_at" = '2017-08-29 17:11:59+0300' WHERE "id" = '8149132e-2e28-4423-bc72-471751b5fcd3';
所以问题可能出现在 Doctrine 的内部查询构建器中。
当我明确定义 nullable=true 时,
* @ORM\JoinColumn(name="`archived_by`", referencedColumnName="id", nullable=true)
没有任何变化,正如预期的那样,因为它已经是默认设置。
在 Doctrine2 documentation 中,我找不到任何东西。
我只需要将 archivedBy 属性 设置为 null。
详情:
- 我使用 postgresql。 (archived_by 列在那里可以为空。)
- Doctrine ORM 2.5 & Doctrine Bundle 1.6
试试这个:
使用这个注释:
@ORM\JoinColumn(name="`archived_by`", referencedColumnName="id", nullable=true)
进入命令行后:
bin/consone doctrine:schema:update --force
删除缓存并重试:
$country->setArchivedBy(null);
这对我来说很好
很难相信这个问题是关于 Doctrine 限制的。
当我删除列名注释中的引号时,它按预期工作;这样,
* @ORM\JoinColumn(name="archived_by", referencedColumnName="id")
而不是
* @ORM\JoinColumn(name="`archived_by`", referencedColumnName="id")
然后 Doctrine 产生 SQL 查询
SET archived_by = NULL
它可能被报告为错误,但它不是错误。在Doctrine2 documentation中明确指出:
You cannot quote join column names.
所以删除不必要的引号可以解决问题。
我有一个像用户实体一样工作的身份验证实体,以及一个具有与身份验证实体单向相关的 属性 的国家/地区实体:
/**
* @var Authentication
*
* @ORM\ManyToOne(targetEntity="Authentication")
* @ORM\JoinColumn(name="`archived_by`", referencedColumnName="id")
*/
private $archivedBy;
/**
* @param Authentication $archivedBy
* @return Country
*/
public function setArchivedBy(Authentication $archivedBy = null)
{
$this->archivedBy = $archivedBy;
return $this;
}
至于文档,连接列默认可为空。
当我想在侦听器中将用户设置为这个 archivedBy 属性 时,它按预期工作:
public function preRemove(LifecycleEventArgs $event)
{
$entity = $event->getObject();
$entity->setArchivedBy($this->tokenStorage->getToken()->getUser());
$om = $event->getObjectManager();
$om->persist($entity);
$om->flush();
}
但是当我想在它的控制器中将这个 属性 设置为空(想删除关系)时,它没有按预期工作:
$country->setArchivedBy(null);
在 Symfony 分析器的 Doctrine2 调试中,我看到 sql 查询不包括 "SET archived_by = null",这样:
UPDATE "country" SET "archived_at" = NULL, "updated_by" = '80fa198a-3216-46cd-aedb-64ce7ff27801', "updated_at" = '2017-08-29 17:11:59+0300' WHERE "id" = '8149132e-2e28-4423-bc72-471751b5fcd3';
所以问题可能出现在 Doctrine 的内部查询构建器中。
当我明确定义 nullable=true 时,
* @ORM\JoinColumn(name="`archived_by`", referencedColumnName="id", nullable=true)
没有任何变化,正如预期的那样,因为它已经是默认设置。
在 Doctrine2 documentation 中,我找不到任何东西。
我只需要将 archivedBy 属性 设置为 null。
详情:
- 我使用 postgresql。 (archived_by 列在那里可以为空。)
- Doctrine ORM 2.5 & Doctrine Bundle 1.6
试试这个:
使用这个注释:
@ORM\JoinColumn(name="`archived_by`", referencedColumnName="id", nullable=true)
进入命令行后:
bin/consone doctrine:schema:update --force
删除缓存并重试:
$country->setArchivedBy(null);
这对我来说很好
很难相信这个问题是关于 Doctrine 限制的。
当我删除列名注释中的引号时,它按预期工作;这样,
* @ORM\JoinColumn(name="archived_by", referencedColumnName="id")
而不是
* @ORM\JoinColumn(name="`archived_by`", referencedColumnName="id")
然后 Doctrine 产生 SQL 查询
SET archived_by = NULL
它可能被报告为错误,但它不是错误。在Doctrine2 documentation中明确指出:
You cannot quote join column names.
所以删除不必要的引号可以解决问题。