【问题标题】:Can't get Doctrine form to work in Zend 2无法让 Doctrine 形式在 Zend 2 中工作
【发布时间】:2015-04-06 00:48:53
【问题描述】:

我试图弄清楚如何在 Zend 中使用注释以及 Doctrine hydrators 和 builders,但似乎无法弄清楚哪里出了问题。我设置了两个实体,一个称为“列表”,一个称为“列表类型”。 Listtypes 定义列表的类型(允许我在类别中创建列表)。我最初尝试使用“ComposedObject”注释,但决定我宁愿使用 Listype 对象中的注释来添加/编辑这些项目,而不是作为获取 Lists 表单的选择列表作为字段集的一种方式。所以我尝试使用两个字段集,现在我只是在注释中排除 ListtypeId(referencedColumnName)和 listtype(来自 ManyToOne 关系的对象),并在 Doctrine FormBuilder 从创建表单之后手动添加选择器其他领域:

    $list = new \Application\Entity\Lists();

    $builder = new \DoctrineORMModule\Form\Annotation\AnnotationBuilder( $this->getEntityManager());
    $form = $builder->createForm( $list );
    $form->setHydrator(new \DoctrineModule\Stdlib\Hydrator\DoctrineObject($this->getEntityManager(),'Application\Entity\Lists'));

    $form->add(
        array(
            'name' => 'ListtypeId',
            'type' => 'DoctrineORMModule\Form\Element\DoctrineEntity',
            'options' => array(
                'label'          => 'Select List Type',
                'object_manager' => $this->getEntityManager(),
                'target_class'   => 'Application\Entity\Listtypes',
                'property'       => 'ListtypeId',
                'label_generator' => function($targetEntity) {
                    return $targetEntity->getListtypeId() . ' - ' . $targetEntity->getListtypeName();
                },
                'display_empty_item' => true,
                'empty_item_label'   => '---',
                'find_method' => array(
                    'name'   => 'findBy',
                    'params' => array(
                        'criteria' => array(),
                        'orderBy'  => array('ListtypeId' => 'ASC'),
                    ),
                ),
                'attributes' => array(
                    'required' => 'required'
                )
            ),
        )
    );

我觉得这一切都很好,我想我明白它在做什么。它试图坚持现在给我的结果。我有这个选择器显然返回了 ListtypeId,所以我最终得到了两个相关参数,ListName 和 ListtypeId:

    $form->bind($list);

    if ($this->request->isPost()) {
        $data['ListName'] = $this->request->getPost('ListName');
        $data['ListtypeId'] = intval($this->request->getPost('ListtypeId'));

        $listId = $this->request->getPost('ListId');
        if((intval($listId) > 0) && ($listId != $list->getId())) {
            $data['ListId'] =  $this->request->getPost('ListId');
        }

        $form->setData($data);
        //$this->getDefMapper()->setListtype($list,$Listtype['ListtypeId']);

        if ($form->isValid()) {
            $this->getDefMapper()->getEntityManager()->persist($list);
            $this->getDefMapper()->getEntityManager()->flush();
        }
    }

结果是一个数组,其中包含我输入的名称和选择器中的 id。一切看起来都很好。所以我做了一个 $form->setData($data); - 没有错误,查看 $list 对象,设置了 Name 并设置了 ListtypeId,但 hydrator 没有为 $listtype 属性创建对象(我认为它应该这样做 - 我还必须设置一个'listtype' 的键或以其他方式自行设置,例如使用注释掉的代码行?)

现在,让我摸不着头脑的是,正如我所说,当我在持久化之前检查 xdebug 中的代码时,ListtypeId 在 $list 实例中的值为“2”。但是当持久性触发时,我得到的是:

An error occurred
An error occurred during execution; please try again later.
Additional information:
Doctrine\DBAL\Exception\NotNullConstraintViolationException
File:
R:\TheWild\ZF2Skel\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\AbstractMySQLDriver.php:112
Message:
An exception occurred while executing 'INSERT INTO Lists (ListtypeId, ListName) VALUES (?, ?)' with params [null, "hoodoo"]:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'ListtypeId' cannot be null

我想知道的是,为什么?它似乎是在调用持久化时设置的。

【问题讨论】:

  • 玩得越多,我就能让它发挥作用,但我仍然不明白所涉及的所有“为什么”。我将该字段从 ListtypeId 重命名为简单的“listtype”以匹配对象句柄属性名称而不是 Id 字段。结果是 hydrator 用适当的 Listtypes 记录的实例填充了 $list 中的 listitem 对象句柄。但是 ListtypeId 仍然是空白的。然后,persist() 调用起作用了。所以在你坚持之前,Doctrine 不会填充引用?

标签: php forms doctrine-orm zend-framework2 annotations


【解决方案1】:

您似乎正在尝试使用您手动设置的特定 ListtypeId 在数据库中创建记录。

信息很明确:

消息: 使用参数 [null, "hoodoo"] 执行“INSERT INTO Lists (ListtypeId, ListName) VALUES (?, ?)”时发生异常:

ListtypeId 的值是null,这是因为 Doctrine 忽略它并一如既往地继续为您的实体生成 ID。

所以你需要在调用persist方法之前设置你的实体的ID,并且还要更改generator strategy。只需添加此代码,它应该可以工作:

if ($form->isValid()) {
        $list->setListtypeId($data['ListtypeId']);
        $em->getClassMetaData(get_class($list))
           ->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());

        $this->getDefMapper()->getEntityManager()->persist($list);
        $this->getDefMapper()->getEntityManager()->flush();
}

Force entity ID on persist

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-20
    • 1970-01-01
    • 2023-04-04
    相关资源
    最近更新 更多