Doctrine2反向持久性不能以嵌套形式工作

时间:2014-12-19 06:01:38

标签: forms symfony doctrine-orm nested-forms

我正在创建一个与MotorsAds实体链接的MotorsAdsFile实体。对于每个MotorsAds,我们可以附加许多MotorsAdsFile

我的目标是为MotorsAds创建一个表单,只需点击一下按钮即可添加MotorsAdsFile。在这里,我正在尝试实施embeded forms

我的问题是我收到了这个错误:

使用参数执行'INSERT INTO MotorsAdsFile(filename,motors_id)VALUES(?,?)'时出现异常[“5493b613839d7_2012-07-02 22.06.00.jpg”,null]:

SQLSTATE [23000]:完整性约束违规:1048列'motors_id'不能为空

可能还没有持续保持MotorsAds对象:这就是Column'rave_id'为空的原因。你能帮忙解决这个问题吗?

我错过了什么吗?


1。实体的定义

MotorsAdsFile

<?php

namespace Minn\AdsBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\Validator\Constraints as Assert;
use Vich\UploaderBundle\Mapping\Annotation as Vich;

/**
 * @ORM\Entity
 * @Vich\Uploadable
 */
class MotorsAdsFile {

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    public $id;

    /**
     * @Assert\File(
     *     maxSize="5M",
     *     mimeTypes={"image/png", "image/jpeg"}
     * )
     * @Vich\UploadableField(mapping="motors_files", fileNameProperty="filename")
     */
    protected $file;

    /**
     * @ORM\Column(type="string", length=255, name="filename")
     * @var string $filename
     */
    protected $filename;

    /**
     * @ORM\ManyToOne(targetEntity="Minn\AdsBundle\Entity\MotorsAds", inversedBy="files")
     * @ORM\JoinColumn(nullable=false,onDelete="CASCADE")
     */
    private $motors;

    /**
     * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $file
     */
    public function setFile(File $file) {
        $this->file = $file;
    }

    /**
     * @return File
     */
    public function getFile() {
        return $this->file;
    }

    /**
     * @param string $filename
     */
    public function setFilename($filename) {
        $this->filename = $filename;
    }

    /**
     * @return string
     */
    public function getFilename() {
        return $this->filename;
    }

    /**
     * Set motors
     *
     * @param \Minn\AdsBundle\Entity\MotorsAds $motors
     * @return MotorsAds
     */
    public function setMotors(\Minn\AdsBundle\Entity\MotorsAds $motors) {
        $this->motors = $motors;
        return $this;
    }

    /**
     * Get motors
     *
     * @return \Minn\AdsBundle\Entity\MotorsAds
     */
    public function getMotors() {
        return $this->motors;
    }
}

MotorsAds

<?php

namespace Minn\AdsBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * MotorsAds
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Minn\AdsBundle\Entity\MotorsAdsRepository")
 * @ORM\HasLifecycleCallbacks()
 */
class MotorsAds {
    // ...
    /**
     * @ORM\OneToMany(targetEntity="Minn\AdsBundle\Entity\MotorsAdsFile",
     *                mappedBy="motors",  
     *                cascade={"persist", "remove"})
     * @ORM\JoinColumn(nullable=true)
     */
    private $files;
    public function __construct() {
        $this->files = new \Doctrine\Common\Collections\ArrayCollection();
        $this->favorites = new \Doctrine\Common\Collections\ArrayCollection();
    }

    public function getFiles() {
        return $this->files;
    }

    public function addFile(MotorsAdsFile $file) {
        $this->files[] = $file;
        return $this;
    }

    public function removeFile(MotorsAdsFile $file) {
        $this->files->removeElement($file);
    }
    // ...
}

2。表格

MotorsAdsFileType

class MotorsAdsFileType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->add('file', 'file',array('required' => false));
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver) {
        $resolver->setDefaults(array(
            'data_class' => 'Minn\AdsBundle\Entity\MotorsAdsFile'
        ));
    }

    public function getName() {
        return 'MotorsAdsFiletype';
    }

}

MotorsAdsType

class MotorsAdsType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options) {
        // ...some code here
        $builder->add('files','collection',array('type'=> new MotorsAdsFileType(),
                        'allow_add'=> true,
                        'allow_delete' => true,
                        'by_reference' => true));
    }
    public function setDefaultOptions(OptionsResolverInterface $resolver) {
        $resolver->setDefaults(array(
            'data_class' => 'Minn\AdsBundle\Entity\MotorsAds'
        ));
    }

    public function getName() {
        return 'MotorsAdstype';
    }
}

1 个答案:

答案 0 :(得分:3)

我找到了解决方案......

必须做两件事:

<强>(1)

public function buildForm(FormBuilderInterface $builder, array $options) {
    // ...some code here
    $builder->add('files','collection',array('type'=> new MotorsAdsFileType(),
                    'allow_add'=> true,
                    'allow_delete' => true,
                    'by_reference' => false)); // it has to be set to false and not true
}

<强>(2)

public function addFile(MotorsAdsFile $file) {
    $file->setMotors($this);      // you have to add this line too
    $this->files[] = $file;
    return $this;
}