案件有点错综复杂。我有一个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))
我的实体Workflow
与Project
类具有单向 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
没有问题。
答案 0 :(得分:2)
您的问题是,您正试图从EntityManager
保存实体detached。 Workflow
,Project
个实体标记为NEW
,并计划进行插入而非更新。在探索会话project->fuel
的{{1}}关联期间,找到具有非空Project
值的其他Fuel
实体。但它已分离,id
中找不到id
,因此会引发异常。
应该在数据库中具有相应行但由EntityManager
加载的实体(在您的示例中从会话中未反序列化)应该merged到EntityManager
。您应该合并所有EntityManager
,Workflow
,Project
个实例。最简单的方法是为级联合并Fuel
配置workflow->project
和project->fuel
关联,并仅合并会话cascade: [merge]
。
Workflow
请注意,这会自动将实体字段值替换为从会话中提取的字段值。
答案 1 :(得分:1)
由于您使用重定向进行路由,因此正在创建一个新请求来加载表单的第二部分。此时,已经重建了identityMap,并且没有引用先前加载的会话对象(工作流)的映射(long id)。尝试再次从数据库中检索对象,并使用会话对象的值设置属性。
PS:可能有一种更清洁的方法可以做到这一点,我不知道。