0

我将 Symfony2 与 mongodb 和教义-odm 一起使用,它们有一个奇怪的行为。我有一个 importFile 文档和一个上下文文档。contexte 文档被引用到 importFile 一中,如下所示:

/**
* @MongoDB\Document
*/
class ImportFile
{
[...]
/**
 * @MongoDB\ReferenceOne(targetDocument="Contexte")
 */
private $contexte;

(getter 和 setter 都可以)。

我的上下文文档已经存在,并且存在于会话中。如果我转储上下文对象,我确实拥有所有必需的对象信息、他的 ID 和他的所有属性。

在我的控制器中,我想将此上下文对象保存到我的 importFile 之一中:

$dm = $this->getDocumentManager();
$importFile->setContexte($contexte); // contexte object already exists and persisted
$dm->persist($importFile);
$dm->flush();

它看起来很简单,应该像那样工作,但是在冲洗时,我得到一个 mongodb 错误:

无法创建没有标识符的 DBRef。UnitOfWork::getDocumentIdentifier() 没有返回类 Contexte 的标识符

我不知道我做错了什么。有什么帮助吗?

4

2 回答 2

0

你没有做过 var_dump($importFile) 也许当你检索对象时,它只是空

于 2014-12-10T19:31:34.283 回答
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
                             }
                         ]
                    ]
                ],
            ],
            //...           
        ];
    }
}
于 2015-05-19T23:39:54.897 回答