如何仅使用Doctrine执行实体层次的第一级?
我正在将ZF3应用程序的DBAL迁移到Doctrine,并且希望一步一步地继续。目前我正在使用Mapper
对象的层次结构。像FooEntity
层次结构中的每个实体都有一个根据FooMapper
。嵌套实体的保存通过嵌套Mapper
来执行。每个Mappers
将其实体保存为Zend\Db\Sql\Insert
或Zend\Db\Sql\Update
,并为子实体调用适当的Mapper
,如BarMapper
的BarEntity
。现在如何仅使用Doctrine执行实体层次的第一级?
,之前我主义的便捷功能开始喜欢cascade={"persist"}
,我想保持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\[email protected] 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.
所以,学说似乎试图拯救其子实体整个实体,并在一个尝试失败较低的水平。但为什么?我没有激活任何cascade
选项,并期望Doctrine只保存*别。
为什么学说试图保存整个实体而不仅仅是顶层?如何获得它只保存给定实体的顶层?
,因为你在AbstractEndpoint->externalServer
有一个新的实体(尚未持久化),并作为cascade={"persist"}
换句话说,你刚刚创建了一个新的实体ExternalServer
并没有坚持就这个领域没有被标注你得到这个错误并将其添加为AbstractEndpoint->externalServer
实体,该实体未被注释为cascade={"persist"}
因此,教义最终拥有这个新实体并且不知道如何处理它。为了不丢失任何数据,引发这个异常。
为了解决这个问题,你可以做两件事情:
- 添加
$this->entityManager->persist($externalServer);
创建ExternalServer
实体 - 标注
AbstractEndpoint->externalServer
与cascade={"persist"}
之后。你不想这样做,因为你只想把*实体保存到数据库中,所以你需要手动保存或不添加它是一种关系。
现在回答你的问题:
但是,为什么?我没有激活任何级联选项,并期望Doctrine只保存*别。
以某种方式通过对象模型中的关系原则下降到ExternalServer
实体并发现它处于未执行状态。您不能仅保存链接到关系数据库中的未记录记录的顶层对象层次结构。如果你不想让学说为你做 - 你必须自己处理这种情况,或从关系中删除不存在的实体
我不认为有办法。新的实体错误消息基本上是一个警告,您需要启用级联。鉴于您在两个对象之间存在关系,Doctrine将尝试坚持它。你当然可以删除关系映射。 – Cerad
@Cerad感谢您的评论。也许我理解'cascade = {“persist”}错误。我的期望是,对于'cascade = {“persist”}'注释,相关的对象被保存,没有 - 没有。但是,如果级联保存也没有'cascade = {“persist”}',那么这个注释是什么意思呢? – automatix
这又是一个警告。一些人喜欢明确坚持所有的儿童实体,在这种情况下不需要级联,警告消失。总的来说,关于ORM学说的一件事是,它只是以某种方式做事。你要么住在一起,要么不使用它。就个人而言,如果我已经有一个工作dbal的系统,那么我会坚持下去。 – Cerad