Dan*_*ger 7 symfony-forms symfony doctrine-orm
保存表单提交数据时,我无法持久保存新实体实例,其中实体与另一个实体具有可空的关联,并且我尝试将其设置为null.在为表单创建新的实体实例后,将提交的请求绑定到表单并持久化并刷新实体实例,具体取决于我如何填充关联实体的属性,我要么得到
UnexpectedTypeException: Expected argument of type "object or array", "NULL" given (如果设置为null),或InvalidArgumentException: A new entity was found through the relationship 'AccessLog#document' that was not configured to cascade persist operations for entity (如果设置为相关实体的新的空实例,我不想保留它).如果我设置了cascade persist,它会尝试在相关表中创建一个记录(db中的数据模型不允许),即使没有数据可以保留.如果设置级联持久化是要走的路,我该如何阻止它尝试创建新记录?处理这个问题的最佳方法是什么?
注意,无论关联是设置为单向还是双向,行为都是相同的.
细节:
我有一个与另一个实体(缩写)有多对一关联的实体:
/** @Entity */
class AccessLog
{
/** @Id @Column(type="integer") */
private $access_log_id;
/** @Column(type="integer", nullable=true) */
private $document_id;
/**
* @ManyToOne(targetEntity="Document", inversedBy="access_logs", cascade={"persist"})
* @JoinColumn(name="document_id", referencedColumnName="document_id")
*/
private $document;
// plus other fields
// plus getters and setters for all of the above...
}
Run Code Online (Sandbox Code Playgroud)
相关实体没什么特别的:
/** @Entity */
class Document
{
/** @Id @Column(type="integer") */
private $document_id;
/** @Column(length=255) */
private $name;
/** @OneToMany(targetEntity="AccessLog", mappedBy="document") */
private $access_logs;
// plus other fields
// plus getters and setters for all of the above...
}
Run Code Online (Sandbox Code Playgroud)
我有一个Symfony表单,用于输入新的AccessLog记录的数据:
class AccessLogFormType extends AbstractType
{
public function getName()
{
return 'access_log_form';
}
public function getDefaultOptions(array $options)
{
return array('data_class' => 'AccessLog');
}
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('access_log_id', 'hidden');
$builder->add('document_id', 'hidden', array(
'required' => false
));
$builder->add('document', new DocumentType(), array(
'label' => 'Document',
'required' => false
));
//...
}
}
Run Code Online (Sandbox Code Playgroud)
使用以下支持类型定义:
class DocumentType extends AbstractType
{
public function getName()
{
return 'document';
}
public function getDefaultOptions(array $options)
{
return array('data_class' => 'Document');
}
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('name', 'text', array(
'required' => false
));
}
}
Run Code Online (Sandbox Code Playgroud)
我的控制器包括以下内容:
public function save_access_log_action()
{
$request = $this->get('request');
$em = $this->get('doctrine.orm')->getEntityManager();
$access_log = null;
if ($request->getMethod() === 'POST') {
$data = $request->request->get('access_log_form');
if (is_numeric($data['access_log_id'])) {
$access_log = $em->find('AccessLog', $data['access_log_id']);
} else {
$access_log = new AccessLog();
}
if (is_numeric($data['document_id'])) {
$document = $em->find('Document', $data['document_id']);
$access_log->set_document($document);
} else {
// Not calling set_document() since there shouldn't be a
// related Document entity.
}
$form = $this->get('form.factory')
->createBuilder(new AccessLogFormType(), $access_log)
->getForm();
$form->bindRequest($request);
if ($form->isValid()) {
$em->persist($access_log);
$em->flush();
}
} else {
// ... (handle get request)
}
return $this->render('access_log_form.tpl', array(
'form' => $form->createView()
));
}
Run Code Online (Sandbox Code Playgroud)
上述代码在更新现有访问日志条目或创建新条目并且在表单中选择文档时工作正常,但如果没有选择文档则不行.
假设无法更改数据模型,如何在不持久保存新Document实体的情况下持久保存新的AccessLog实体?
您是否阅读过Doctrine2 文档中有关传递持久性/级联操作的页面?我认为如果该文档存在,您首先需要remove它,如果不存在,那么您不应该调用setDocument(). 为了避免第二个错误,\xc2\xa7 解释了如何配置级联(请参阅最后一个代码片段)。
| 归档时间: |
|
| 查看次数: |
16382 次 |
| 最近记录: |