Symfony 2多对一不能为空

时间:2014-05-20 22:08:01

标签: symfony doctrine-orm persist

我有:

    An exception occurred while executing 'INSERT INTO image (image_name, artiste_id) VALUES (?, ?)' with params ["537bd9df69db9.png", null]:

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

我与公司有一对一的关系' image'和'艺术家'。我真的没有看到问题所在。

我的实体图片:

 <?php

namespace Acme\ArtisteBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;

use Acme\ArtisteBundle\Entity\Artiste;

/**
 * Acme\ArtisteBundle\Entity\Image
 *
 * @ORM\Table(name="image")
 * @ORM\Entity(repositoryClass="Acme\ArtisteBundle\Entity\ImageRepository")
 * @ORM\HasLifecycleCallbacks
 * @Vich\Uploadable
 */
class Image
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @Assert\File(
     *     maxSize="1M",
     *     mimeTypes={"image/png", "image/jpeg", "image/pjpeg"}
     * )
     * @Vich\UploadableField(mapping="product_image", fileNameProperty="imageName")
     *
     * @var File $image
     */
    public $image;

    /**
     * @var string $imageName
     * @ORM\Column(type="string", length=255, name="image_name", type="integer", nullable=false)
     */
    protected $imageName;

    /**
     * @ORM\ManyToOne(targetEntity="Acme\ArtisteBundle\Entity\Artiste", inversedBy="image", cascade={"remove"})
     * @ORM\JoinColumn(name="artiste_id", referencedColumnName="id", nullable=false)
     */
    private $artiste;

    /**
    * Set artiste
    *
    * @param \Acme\ArtisteBundle\Entity\Artiste $artiste
    */
    public function setArtiste(\Acme\ArtisteBundle\Entity\Artiste $artiste)
    {
        $this->artiste = $artiste;
    }

    /**
    * Get artiste
    *
    * @return \Acme\ArtisteBundle\Entity\Artiste
    */
    public function getArtiste()
    {
        return $this->artiste;
    }

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

    /**
     * Get Image
     * @return File
     */
    public function getImage()
    {
        return $this->image;
    }

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

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

和我的实体Artiste

    <?php

namespace Acme\ArtisteBundle\Entity;

use FOS\UserBundle\Entity\User as BaseUser;
use Acme\ArtisteBundle\Entity\Image;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
use Vich\UploaderBundle\Mapping\Annotation as Vich;

/**
 * Artiste
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Acme\ArtisteBundle\Entity\ArtisteRepository")
 * @ORM\HasLifecycleCallbacks()
 */
class Artiste extends BaseUser
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var string
     *
     * @ORM\Column(name="valideAdmin", type="boolean", nullable=true)
     */
    private $valideAdmin = '0';

    /**
     * @ORM\OneToMany(targetEntity="Acme\ArtisteBundle\Entity\Image", mappedBy="artiste", cascade={"persist", "remove"})
     */
    protected $image;

    public function __construct()
    {
        trigger_error(sprintf('%s is deprecated. Extend FOS\UserBundle\Model\User directly.', __CLASS__), E_USER_DEPRECATED);
        parent::__construct();

        $this->image = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get image
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getImage() {
        return $this->image;
    }

    /**
     * Set image
     *
     * @param \Doctrine\Common\Collections\Collection $image
     */
    public function setImage(\Doctrine\Common\Collections\Collection $image)
    {
        $this->image = $image;
    }

    /**
     * Add image
     *
     * @param \Acme\ArtisteBundle\Entity\Image $image
     */
    public function addImage(\Acme\ArtisteBundle\Entity\Image $image)
    {
        $this->image[] = $image;
    }

    /**
     * Remove image
     *
     * @param \Acme\ArtisteBundle\Entity\Artiste $image
     */
    public function removeImage(\Acme\ArtisteBundle\Entity\Artiste $image)
    {
        $this->image->removeElement($image);
    }
}

和我对FOS的注册行动

namespace Unikness\ArtisteBundle\Controller;

use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Event\GetResponseUserEvent;
use FOS\UserBundle\Event\UserEvent;
use FOS\UserBundle\Event\FilterUserResponseEvent;

use Symfony\Component\DependencyInjection\ContainerAware;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use FOS\UserBundle\Model\UserInterface;

use Acme\ArtisteBundle\Entity\Image;

use FOS\UserBundle\Controller\RegistrationController as BaseController;

class RegistrationController extends ContainerAware
{
    public function registerAction(Request $request)
    {
        /** @var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
        $formFactory = $this->container->get('fos_user.registration.form.factory');
        /** @var $userManager \FOS\UserBundle\Model\UserManagerInterface */
        $userManager = $this->container->get('fos_user.user_manager');
        /** @var $dispatcher \Symfony\Component\EventDispatcher\EventDispatcherInterface */
        $dispatcher = $this->container->get('event_dispatcher');

        $user = $userManager->createUser();
        $user->setEnabled(true);

        $event = new GetResponseUserEvent($user, $request);
        $dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);

        if (null !== $event->getResponse()) {
            return $event->getResponse();
        }

        $form = $formFactory->createForm();
        $form->setData($user);

        $image = new Image();

        if ('POST' === $request->getMethod()) {
            $form->bind($request);

            if ($form->isValid()) {
                $event = new FormEvent($form, $request);
                $dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);

                $userManager->updateUser($user);
                $image->setArtiste($user);
                $em = $this->container->get('doctrine')->getEntityManager();
                $em->persist($image);
                $em->flush();

                if (null === $response = $event->getResponse()) {
                    $url = $this->container->get('router')->generate('fos_user_registration_confirmed');
                    $response = new RedirectResponse($url);
                }

                $dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));

                return $response;
            }
        }

        return $this->container->get('templating')->renderResponse('FOSUserBundle:Registration:register.html.'.$this->getEngine(), array(
            'form' => $form->createView(),
        ));
    }

我坚持但我总是空着。任何帮助将不胜感激:)

3 个答案:

答案 0 :(得分:0)

尝试添加&#34;坚持&#34; ManyToOne注释中的选项

/**
 * @ORM\ManyToOne(targetEntity="Acme\ArtisteBundle\Entity\Artiste", inversedBy="image", cascade={"remove","persist"})
 * @ORM\JoinColumn(name="artiste_id", referencedColumnName="id", nullable=false)
 */
private $artiste;

答案 1 :(得分:0)

为了确保双向关系,有一个技巧:

在您的Artiste类中,修改您的setter setImage,如下所示:

public function setImage(\Doctrine\Common\Collections\Collection $image)
{
    foreach ($image as $img) {
        $img->setArtiste($this);
    }
    $this->image = $image;
}

此外,为了更好地阅读您的代码,我建议重命名&#34; image&#34;在你的班级艺术家的场地&#34;图像&#34;因为这个字段是实体Image的集合。

我还在这篇文章doctrine2: in a one-to-many bidirectional relationship, how to save from the inverse side?中读到你可以这样做(选择这两个解决方案,如果你创建图像,第二个解决方案很有趣,然后将Artiste附加到创建的图像=&#34 ;从反面保存&#34;):

你的班级中的

图像修改setter setArtiste,如下所示:

public function setArtiste($artiste)
{
    $this->artiste = $artiste;  
    $artiste->addImage($this);
}

答案 2 :(得分:0)

这应该有效

public function addImage(\Acme\ArtisteBundle\Entity\Image $image)
{
    if(!$this->image->contains($image)){
        $this->image[] = $image;
        $image->setArtiste($this);
    }
}