我需要一些建议。我在使用Doctrine 2和Doctrine Orm模块的ZF2项目中。 我使用doctrine模块提供的服务处理身份验证。结果是,在身份验证之后,我在我的身份验证服务中有身份(由getIdentity()方法返回),该身份是我的用户实体的一个实例。
我有两个实体:用户和组。在具有该组的用户实体中定义了多对一关系(一个用户属于一个组,一个组具有多个用户)。基本的东西。
当连接用户需要在CRUD中编辑自己的组时,我的问题出现了。
我处理CRUD的方式很简单:我在我的实体的注释中定义了我的表单,并指定了Doctrine Hydrator并使用了Doctrine Object Select。除了编辑一个人自己的小组外,每件事情都很完美。
我理解的是:由于我的多对一关系处于延迟加载提取模式,因此在身份验证之后,doctrine的身份映射包含用户组作为代理的实例。当用户到达编辑操作时,会发生以下情况:
/*
Code that get the goup id to edit from request
*/
if (!empty($id)) {
$entity = $groupRepository->find($id);
}
$builder = new AnnotationBuilder();
$this->form = $builder->createForm($entity);
结果是,当编辑不在学说标识图中的任何组作为代理实例时,每件事都可以。但是,如果我需要编辑的实体已作为代理实例存在于身份映射中,则表单工厂无法找到我的实体中定义的注释,并且它会中断。 也许我的方式是一种不好的做法?我想使用注释来构建我的表单。
我能找到的唯一解决办法(我猜这是一种可怕的方法)是改变我的代码:
/*
Code that get the goup id to edit from request
*/
if (!empty($id)) {
$em->clear(); <== NEW LINE HERE
$entity = $groupRepository->find($id);
}
$builder = new AnnotationBuilder();
$this->form = $builder->createForm($entity);
理论上,调用clear()来分离所有实体应该不是我的用例中的问题因为我知道我只想编辑组实体但我想这可能不是正确的事情。
另一个解决方案(但尚未尝试):创建一个我传递给AnnotationBuilder的自定义FormFactory。然后,此自定义FormFactory将在从注释启动表单创建之前检测实体的类型。如果它是一个代理,那么它应该得到“真正的”类的注释?
或许我错过了一些简单的东西?
答案 0 :(得分:2)
我有点惊讶的是,当你通过代理时这不能正常工作,但我同意你当前的解决方案很糟糕:)。你可以这样解决它:
// collect the class from the entity or proxy
$className = \Doctrine\Common\Util\ClassUtils::getClass($entity);
$builder = new AnnotationBuilder();
$this->form = $builder->createForm($className);
注释构建器在传递类名时效果很好。上面的代码从代理对象和实体中收集真实的类名,因此这适用于两种情况。
但我仍然建议检查您的配置,因为我几乎可以肯定它也应该可以正常使用代理。