Symfony2 OneToMany - 来自嵌入表单的持久数据

时间:2013-09-08 16:25:41

标签: forms symfony one-to-many relationship

当我想将数据从表单保存到数据库时,我遇到了问题

我有两个简单的实体用户和电话

用户可以拥有多部电话 电话只能有一个用户

数据库表是:

  

用户[id,姓名,电子邮件]

     

电话[id,user_id,phone_number]

我的表格还有以下字段

  • 一个名字
  • 电子邮件
  • 和电话号码

当我填写并提交表单时,我会收到以下例外

  

使用参数[123456,null]执行'INSERT INTO telephone(phone_number,user_id)VALUES(?,?)'时发生异常:

     

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

在调试器栏中,我看到执行了4个查询

  1. START TRANSACTION
  2. INSERT INTO用户(姓名,电子邮件) VALUES (?,?) 参数:{1:'name',2:email@yahoogmail.com}
  3. 插入电话(phone_number,user_id) VALUES (?,?) 参数:{1:123456,2:null}
  4. ROLLBACK
  5. 我理解为什么会发生这种异常,但我不明白为什么user_id获取NULL值。

    这是我的代码 (我省略了某些属性的getter,setter和annotations)

    用户实体

    class User
    {
    
    private $name;
    
    private $email;
    
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;
    
    /** 
     * @var \Acme\FormBundle\Entity\Telephone
     *
     * @ORM\OneToMany(targetEntity="Acme\FormBundle\Entity\Telephone", mappedBy="user", cascade={"ALL"})
     */
    private $telephones;
    
    /**
     * Constructor
     */
    public function __construct()
    {
        $this->telephones = new \Doctrine\Common\Collections\ArrayCollection();
    }
    
    /**
     * Add telephones
     *
     * @param \Acme\FormBundle\Entity\Telephone $telephones
     * @return User
     */
    public function addTelephone(\Acme\FormBundle\Entity\Telephone $telephones)
    {
        $this->telephones[] = $telephones;
        $telephones->setUser($this);
    
        return $this;
    }
    
    /**
     * Remove telephones
     *
     * @param \Acme\FormBundle\Entity\Telephone $telephones
     */
    public function removeTelephone(\Acme\FormBundle\Entity\Telephone $telephones)
    {
        $this->telephones->removeElement($telephones);
    }
    
    /**
     * Get telephones
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getTelephones()
    {
        return $this->telephones;
    }
    }
    

    电话实体

    class Telephone
    {
    private $phoneNumber;
    
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;
    
    /**
     * @var \Acme\FormBundle\Entity\User
     *
     * @ORM\ManyToOne(targetEntity="Acme\FormBundle\Entity\User", inversedBy="telephones")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     * })
     */
    private $user;
    
    /**
     * Set user
     *
     * @param \Acme\FormBundle\Entity\User $user
     * @return Telephone
     */
    public function setUser(\Acme\FormBundle\Entity\User $user = null)
    {
        $this->user = $user;
    
        return $this;
    }
    
    /**
     * Get user
     *
     * @return \Acme\FormBundle\Entity\User 
     */
    public function getUser()
    {
        return $this->user;
    }
    } 
    

    用户类型

    class UserType extends AbstractType
    {
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name')
            ->add('email')
            ->add('telephones', 'collection', array('type' => new TelephoneType()))
            ->add('save it', 'submit');
    }
    
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\FormBundle\Entity\User',
            ));
    }
    
    public function getName()
    {
        return 'user';
    }
    }
    

    TelephoneType

    class TelephoneType extends AbstractType
    {
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('phoneNumber');
    
    }
    
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\FormBundle\Entity\Telephone',
            ));
    }
    
    public function getName()
    {
        return 'telephone';
    }
    }
    

    和我的控制器

    class DefaultController extends Controller
    {
    public function indexAction(Request $request)
    {
        $user = new User();
        $Telephone1 = new Telephone(); 
    
        $user->getTelephones()->add($Telephone1);
    
        $form = $this->createForm(new UserType(), $user);
    
        $form->handleRequest($request);
    
        if ($form->isValid()) {
    
            $em = $this->getDoctrine()->getManager();
            $em->persist($user);
            $em->flush();
    
        }
    
        return $this->render('AcmeFormBundle:Default:index.html.twig', array(
            'form' => $form->createView(),
            ));
    }
    }
    

    对不起这篇长篇文章

    有人能帮帮我吗?

    我会很感激!

2 个答案:

答案 0 :(得分:2)

我替换了

$user->getTelephones()->add($Telephone1);

$user->addTelephone($Telephone1);

在我的控制中

答案 1 :(得分:1)

这是因为您使用getData()而不是persist()。你应该这样做:

if ($form->isValid()) {
    $em = $this->getDoctrine()->getManager();
    $em->persist($user);
    $em->flush();
}