我使用Symfony2和mongodb&具有奇怪行为的教义 - odm。我有一个importFile文档和一个上下文文档。 contexte文档被引用到importFile中,如下所示:
/**
* @MongoDB\Document
*/
class ImportFile
{
[...]
/**
* @MongoDB\ReferenceOne(targetDocument="Contexte")
*/
private $contexte;
(getter和setter都可以。)
我的上下文文档已经存在,并且存在于会话中。如果我转储上下文对象,我确实拥有所有必需的对象信息,带有他的id和他所有的属性。
在我的控制器中,我想将这个contexte对象保存到我的importFile对象中:
$dm = $this->getDocumentManager();
$importFile->setContexte($contexte); // contexte object already exists and persisted
$dm->persist($importFile);
$dm->flush();
它看起来非常简单,应该像那样工作,但在刷新时,我得到一个mongodb错误:
无法创建没有标识符的DBRef。 UnitOfWork :: getDocumentIdentifier()未返回类Contexte
的标识符
我不知道自己做错了什么。有什么帮助吗?
答案 0 :(得分:0)
你在检索对象时没有做过var_dump($ importFile),只是null
答案 1 :(得分:0)
也许它会帮助别人。
在我的情况下,主要问题是验证后ZF2返回标识符的空字符串。
仅当默认值为NULL https://github.com/doctrine/mongodb-odm/blob/master/lib/Doctrine/ODM/MongoDB/UnitOfWork.php#L1017时,Doctrine才会生成新标识符。
我的代码的简化示例(请参阅注释):
namespace Ageme\Project\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Doctrine\ODM\MongoDB\DocumentManager;
class ProjectController extends AbstractActionController {
//...
protected function saveAction() {
/** @var DocumentManager $dm */
$request = $this->getRequest();
$route = $this->getEvent()->getRouteMatch();
$sm = $this->getServiceLocator();
$fm = $sm->get('FormElementManager');
$dm = $sm->get('doctrine.documentmanager.odm_default');
$project = ($project = $dm->find('Ageme\Project\Document\Project', $route->getParam('id')))
? $project
: $sm->get('Ageme\Project\Document\Project');
$form = $fm->get('Ageme\Project\Form\ProjectForm');
$form->bind($project);
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
// after validation $project->getId() === '',
// but for new object must equal $project->getId() === null
$sm->get('ProjectService')->run('save', $project);
$this->flashMessenger()->addSuccessMessage('Project saved');
$this->redirect()->toRoute('default',
['controller' => $route->getParam('controller'), 'lang' => $route->getParam('lang')]
);
}
}
return new ViewModel([
'form' => $form,
]);
}
//...
}
我添加下一个过滤器来解决我的问题
namespace Ageme\Project\Form;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
use DoctrineModule\Persistence\ProvidesObjectManager;
use DoctrineModule\Persistence\ObjectManagerAwareInterface;
class ProjectFieldset
extends Fieldset
implements InputFilterProviderInterface, ObjectManagerAwareInterface {
use ProvidesObjectManager;
public function init() {
$this->setName('project')
->setAttributes(['id' => 'project']);
$this->add([
'type' => 'Zend\Form\Element\Hidden',
'name' => 'id'
]);
//...
}
public function getInputFilterSpecification() {
return [
'id' => [
'required' => true,
'allow_empty' => true,
'filters' => [
[
"name" => "Callback",
"options" => [
"callback" => function ($input) {
return $input ?: null; // this code return correct value
}
]
]
],
],
//...
];
}
}