【发布时间】: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