Symfony - manyToOne关系的未定义的外来属性索引

时间:2017-10-06 14:59:05

标签: php symfony doctrine-orm mapping entitymanager

案件有点错综复杂。我有一个Controller动作editCreateFirstFormPart,它处理Workflow对象的某些字段,并呈现两个分开的表单的适当的第一部分。

如果我使用存储对象的id调用此action方法的路由,则表单将加载所有应该的字段。我在当前会话中存储填充表单的数据库对象,以防用户决定以第二种形式取消编辑:

// Persist all changes of made in the first form part
$manager->persist($workflow);
$manager->flush();

// In case the wolkflow already exists store it in the session
if(!$newWorkflow) $this->get('session')->set($workflowSessionName, $workflowBeforeSubmit);
return $this->redirectToRoute('pec_test_pra_edit_workflow_second_part', array(
    'project'               => $project->getId(),
    'workflow'              => $workflow->getId(),
    'newWorkflow'           => $newWorkflow,

    // Pass the name in the session of the stored workflow to the action method which handles the second form
    'workflowSessionName'   => $workflowSessionName,
));

这就像一个魅力。现在以防万一(我检索)用户通过cancel按钮提交第二个表单我想将存储在数据库中的对象重置为第一个表单部分提交之前的状态。因此,我获取存储在会话中的对象,并希望persist它:

if($sessionObject instanceof Workflow) {
     $manager = $this->getObjectManager();
     $sessionObject = $session->get($workflowSessionName);
     $manager->persist($sessionObject);
     $manager->flush();
}

在这里我收到以下错误:

  

注意:供应商\ doctrine \ orm \ lib \ Doctrine \ ORM \ UnitOfWork.php中的未定义索引:0000000061675b3d0000000022ddb0a6 (第2917行)
  第2917行:return $this->entityIdentifiers[spl_object_hash($entity)];

     

UnitOfWork-> getEntityIdentifier( object (Fuel))//在prepareUpdateData之后调用

     

BasicEntityPersister-> prepareUpdateData(物体(MProject))

我的实体WorkflowProject类具有单向 manyToOne 关系。 MProject类扩展了Project,并且具有类fuel的一个Fuel属性。

所以一个Fuel有许多MProject s oneToMany )和许多MProject有一个{{} 1}} manyToOne )。以下是Fuel文件的相应部分:

.orm.yml

Fuel.orm.yml

内部 'ABundle\Entity\Fuel': ... oneToMany: projects: targetEntity: 'ABundle\Entity\MProject' mappedBy: fuel 类:

Fuel

class Fuel { /** * The collection of projects using the fuel. * * @var \Doctrine\Common\Collections\Collection */ private $projects; ... }

MProject.orm.yml

内部'ABundle\Entity\MProject': repositoryClass: 'ABundle\Repository\MProjectRepository' type: entity manyToOne: fuel: targetEntity: 'ABundle\Entity\Fuel' inversedBy: projects 类:

MProject

use BBundle\Entity\Project as BaseProject; // Origin of Project in my Entity class MProject extends BaseProject implements SearchableTypeAlias { /** * The fuel used by the project. * * @var Fuel */ protected $fuel; ... }

Workflow.orm.yml

内部MyBundle\Entity\Workflow: ... manyToOne: project: targetEntity: BBundle\Entity\Project cascade: [persist] ... 类:

Workflow

我真的不知道我的用例中有什么问题,特别是因为在第一个Controller操作方法中存储use BBundle\Entity\Project; class Workflow { /** * @var Project */ private $project; ... } 对象并调用$workflow没有问题。

如何解决此未定义索引错误?

2 个答案:

答案 0 :(得分:2)

您的问题是,您正试图从EntityManager保存实体detachedWorkflowProject个实体标记为NEW,并计划进行插入而非更新。在探索会话project->fuel的{​​{1}}关联期间,找到具有非空Project值的其他Fuel实体。但它已分离,id中找不到id,因此会引发异常。

应该在数据库中具有相应行但由EntityManager加载的实体(在您的示例中从会话中未反序列化)应该mergedEntityManager。您应该合并所有EntityManagerWorkflowProject个实例。最简单的方法是为级联合并Fuel配置workflow->projectproject->fuel关联,并仅合并会话cascade: [merge]

Workflow

请注意,这会自动将实体字段值替换为从会话中提取的字段值。

答案 1 :(得分:1)

由于您使用重定向进行路由,因此正在创建一个新请求来加载表单的第二部分。此时,已经重建了identityMap,并且没有引用先前加载的会话对象(工作流)的映射(long id)。尝试再次从数据库中检索对象,并使用会话对象的值设置属性。

PS:可能有一种更清洁的方法可以做到这一点,我不知道。