我正在尝试解决有关教义ORM的问题。我有2个父实体:CompanyDoctrineEntity
和ServiceDoctrineEntity
以及与这2个实体关联的1个实体(但不需要关联)OrderLinkRedirectLogDoctrineEntity
。 OrderLinkRedirectLogDoctrineEntity
中的关联定义为:
class OrderLinkRedirectLogDoctrineEntity {
/**
* @Id
* @Column(type="integer")
* @ORM\GeneratedValue()
*
* @var int $id
*/
private $id;
/**
* Many logs have one company. This is the owning side.
*
* @ManyToOne(targetEntity="CompanyDoctrineEntity", cascade="detach")
* @JoinColumn(name="company_id", referencedColumnName="id")
*
* @var CompanyDoctrineEntity $company
*/
private $company;
/**
* Many logs have one service. This is the owning side.
*
* @ManyToOne(targetEntity="ServiceDoctrineEntity", cascade="detach")
* @JoinColumn(name="service_id", referencedColumnName="id")
*
* @var ServiceDoctrineEntity $service
*/
private $service;
}
[我的预期行为是,每当从数据库中删除CompanyDoctrineEntity
或ServiceDoctrineEntity
时,OrderLinkRedirectLogDoctrineEntity
中的关联都会被NULL
ed,我相信cascade="detach"
会做什么,但是出于某种原因,它不起作用,因为出现以下错误:
Fatal error: Uncaught PDOException: SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test_app2`.`logs_order_link_redirects`, CONSTRAINT `FK_6C1CA74CED5CA9E6` FOREIGN KEY (`service_id`) REFERENCES `app_services` (`id`)) in /Users/arvil/Projects/app2.test/public_html/wp-content/themes/app-theme/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:117
Stack trace:
#0 /Users/arvil/Projects/app2.test/public_html/wp-content/themes/app-theme/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php(117): PDOStatement->execute(NULL)
#1 /Users/arvil/Projects/app2.test/public_html/wp-content/themes/app-theme/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php(1054): Doctrine\DBAL\Driver\PDOStatement->execute()
#2 /Users/arvil/Projects/app2.test/public_html/wp-content/themes/app-theme/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php(656): Doctrine\DBAL\Connection->exe in /Users/arvil/Projects/app2.test/public_html/wp-content/themes/app-theme/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php on line 49
nullable
(默认为false),这就是您的外键约束抱怨的原因:logs_order_link_redirects.service_id
(和company_id
)不允许为空。以前这可能不是问题,因为您没有插入没有关系的OrderLinkRedirectLogDoctrineEntity
实体。如果您要说$redirectLog = new OrderLinkRedirectLogDoctrineEntity();
$entityManager->persist($redirectLog);
$entityManager->flush();
您可能会立即触发相同的错误。
而且,我不相信您在这里要层叠= {“ detach”}。分离只会从该实体管理器实例中删除该实体(换句话说:对于正在运行的进程),因此,在分离实体后您对实体所做的任何操作都不会在调用$entityManager->flush()
时反映在数据库中。在下一个请求时,实体将返回到实体管理器中。我相信将
nullable=true
添加到ManyToOne的JoinColumn批注中,例如@JoinColumn(name="company_id", referencedColumnName="id", nullable=true)
将为您提供所需的结果。之后,您需要更新数据库架构,以将更改应用于表。另外,请确保您没有(或添加)反面的orphanRemoval=true
,以便Doctrine在失去其父项时不会自动删除您的实体。我更喜欢将JoinColumn注释也添加到关系中,即使您对Doctrine的默认字段名称选择没问题,也不需要这样做。添加
nullable=false
可以更明确地表明此关系不能为null。如果您没有nullable=true
,则表示存在隐含含义,但是当我开始查看关系并需要知道它们是否可以为null时,我通常会感到困惑,并且我没有足够的精力去积极地进行活动。记住重要属性的默认值。