當保存表單提交數據時,我遇到了一個新的實體實例,其中該實體與另一個實體具有可爲空的關聯時遇到問題,我試圖將其設置爲null。爲表單創建一個新的實體實例,結合提交的請求的形式和堅持和沖洗的實體實例,這取決於我如何填充爲關聯實體的財產之後,我要麼得到Symfony2形式:我如何堅持一個可爲空的關聯的實體?
UnexpectedTypeException: Expected argument of type "object or array", "NULL" given
(如果設置爲空),或InvalidArgumentException: A new entity was found through the relationship 'AccessLog#document' that was not configured to cascade persist operations for entity
(如果設置爲相關實體的新的空實例,我不想堅持)。
如果我設置了級聯堅持,它試圖創建的相關表中的記錄(這是不是在數據庫中的數據模型允許的),即使沒有數據爲它堅持。如果設置cascade persist是要走的路,那麼我該如何防止它嘗試創建新記錄?處理這個問題的最好方法是什麼?
注意,無論關聯設置爲單向還是雙向,行爲都是相同的。
詳情:
我有一個多到一的關聯實體與另一個實體(簡稱):
/** @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...
}
相關實體是沒有任何幻想:
/** @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...
}
我有新的ACCESSLOG記錄輸入數據的Symfony的形式:
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
));
//...
}
}
用下面的支撐類型定義:
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
));
}
}
我的控制器包括以下:更新現有的訪問日誌條目或創建一個新的時
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()
));
}
上面的代碼工作正常,並在表單中選擇一個文檔,但如果沒有選擇文檔,則不會。
假設數據模型不能改變,我該如何去堅持一個新的AccessLog實體而不需要保留一個新的Document實體?
爲什麼你需要做'setDocument(null)'?爲什麼不不叫'setDocument'? – greg0ire