【发布时间】:2017-09-26 11:33:22
【问题描述】:
我正在将 ZF3 应用程序的 DBAL 迁移到 Doctrine,并希望逐步进行。目前我正在使用Mapper 对象的层次结构。类似FooEntity 层次结构中的每个实体都有一个相应的FooMapper。嵌套实体的保存由嵌套的Mappers 执行。每个Mappers 将其实体保存为Zend\Db\Sql\Insert 或Zend\Db\Sql\Update,并为子实体调用正确的Mappers,例如BarMapper 为BarEntity。
现在,在我开始使用像 cascade={"persist"} 这样的 Doctrine 便利功能之前,我想保留 Mapper 的层次结构,并使用 persist(...) 和 flush() 执行嵌套实体的顶层保存.
但是当我尝试它时
public function save(AbstractDataObject $dataObject)
{
$newLogicalConnection = $this->logicalConnectionMapper->save($dataObject->getLogicalConnection());
$newUser = $this->userMapper->save($dataObject->getUser());
$dataObject->setLogicalConnection($this->entityManager->find(LogicalConnection::class, $newLogicalConnection->getId()));
$dataObject->setUser($this->entityManager->find(User::class, $newUser->getId()));
$this->entityManager->persist($dataObject);
$this->entityManager->flush();
return $dataObject;
}
我收到一个错误
A new entity was found through the relationship 'MyNamespace\DataObject\AbstractEndpoint#externalServer' that was not configured to cascade persist operations for entity: MyNamespace\DataObject\ExternalServer@000000006098ccff0000000068c23676. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'MyNamespace\DataObject\ExternalServer#__toString()' to get a clue.
因此,Doctrine 似乎尝试保存整个实体及其子实体,但此尝试在较低级别之一失败。但为什么?我没有激活任何cascade 选项,并希望 Doctrine 只保存顶层。
为什么 Doctrine 试图保存整个实体而不仅仅是顶层?以及如何让它只保存给定实体的顶层?
【问题讨论】:
-
我认为没有办法。新的实体错误消息基本上是您需要启用级联的警告。鉴于您在两个对象之间存在关系,Doctrine 将尝试持久化它。您当然可以删除关系映射。
-
@Cerad 感谢您的评论。可能我理解
cascade={"persist"}的意思错了。我的期望是/是,使用cascade={"persist"}注释,相关对象将被保存,而没有 - 不是。但是如果没有cascade={"persist"}也能实现级联保存,那么这个注解有什么意义呢? -
又是一个警告。有些人喜欢显式地保留所有子实体,在这种情况下不需要级联并且警告消失。通常,关于 Doctrine ORM 的一件事是它只是以某些方式做事。你要么忍受它,要么不使用它。就个人而言,如果我已经有一个基于 dbal 的系统,那么我会坚持使用它。
-
@Cerad 那么,是否可以停用级联保存(但不删除关系及其注释)?
标签: php doctrine-orm orm doctrine persistence