Doctrine2 inverse persistance not working in nested forms

瘦欲@ 提交于 2020-01-04 09:18:15

问题


I am creating a MotorsAds entity to which I am linking with MotorsAdsFile entity. For each MotorsAds, we could attach many MotorsAdsFile.

My objective is creating a form for MotorsAds which allows adding MotorsAdsFile just through a click on a button. Here, I am trying to implement the embeded forms.

My problem is that I got that error:

An exception occurred while executing 'INSERT INTO MotorsAdsFile (filename, motors_id) VALUES (?, ?)' with params ["5493b613839d7_2012-07-02 22.06.00.jpg", null]:

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

Probably, the MotorsAds object is not persisted yet: that's why the Column 'motors_id' is null. Could you help in this issue?

Have I missed something?


1. Definition of the entities

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. The forms

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';
    }
}

I


回答1:


I found the solution...

Two things have to be done:

(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;
}


来源:https://stackoverflow.com/questions/27560531/doctrine2-inverse-persistance-not-working-in-nested-forms

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!