Symfony2:一对多关系


Symfony2: One To Many Relationship

在建立一对一关系时遇到一些严重的问题。尝试在Sonata Admin中将"孩子"添加到美女时发生错误。

用:

Symfony2学说索纳塔管理员

一直在尝试遵循指南:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#one-to-many-bidirectional

http://sonata-project.org/bundles/doctrine-orm-admin/2-2/doc/reference/form_field_definition.html

错误:

"关键 - 未捕获的 PHP 异常 Doctrine''ORM''ORMInvalidArgumentException:"发现一个新实体 通过关系 "美化''美女捆绑''实体''美女#儿童"不是 配置为级联实体的持久操作: 美化''美女捆绑''实体''Children@000000000eff91d5000000017f8ca53b. 要解决此问题:显式调用 EntityManager#persist() 此未知实体或配置级联将此关联保留在 例如映射@ManyToOne(..,cascade={"persist"})。如果你 无法找出导致问题的实体实施 '美化''美女捆绑''实体''儿童#__toString()'以获得线索。 在 /Users/gmf/symfony/vendor/doctrine/orm/lib/Doctrine/ORM/ORMInvalidArgumentException.php 91号线"

..

美容管理员.php


<?php
// src/Beautify/BeautiesBundle/Admin/BeautyAdmin.php
namespace Beautify'BeautiesBundle'Admin;
use Sonata'AdminBundle'Admin'Admin;
use Sonata'AdminBundle'Datagrid'ListMapper;
use Sonata'AdminBundle'Datagrid'DatagridMapper;
use Sonata'AdminBundle'Form'FormMapper;
use Knp'Menu'ItemInterface as MenuItemInterface;
use Beautify'CategoryBundle'Entity'Category;
use Beautify'CategoryBundle'Entity'Children;
class BeautyAdmin extends Admin
{
    // Fields to be shown on create/edit forms
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->with('General')
                ->add('name', 'text', array('label' => 'Name'))
                ->add('content', 'textarea', array('label' => 'Content'))
                ->add('imageFile', 'file', array('label' => 'Image file', 'required' => false))
            ->end()
            ->with('Category')
                ->add('category', 'sonata_type_model', array('expanded' => true))
            ->end()
            ->with('Children')
                ->add('children', 'sonata_type_collection', array(), array(
                'edit' => 'inline',
                'inline' => 'table',
                'sortable'  => 'position'
            ))
            ->end()


        ;
    }

    // Fields to be shown on filter forms
    protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        $datagridMapper
            ->add('name')
            ->add('content')
            ->add('category')

        ;
    }
    // Fields to be shown on lists
    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->addIdentifier('name')
            ->add('content')
            ->add('category')
            ->add('imageName')
            ->add('_action', 'actions', array(
                'actions' => array(
                    'show' => array(),
                    'edit' => array(),
                    'delete' => array(),
                )
            ))
        ;
    }
}

美容.php实体


<?php
// src/Beautify/BeautiesBundle/Entity/Beauty.php
namespace Beautify'BeautiesBundle'Entity;
use Doctrine'ORM'Mapping as ORM;
use Symfony'Component'HttpFoundation'File'UploadedFile;
use Symfony'Component'HttpFoundation'File'File;
use Vich'UploaderBundle'Mapping'Annotation as Vich;
use Doctrine'Common'Collections'ArrayCollection;
/** 
* @ORM'Entity
* @ORM'Table(name="beauties")
* @ORM'HasLifecycleCallbacks
* @Vich'Uploadable
*/
 class Beauty
 {
     /**
     * @ORM'OneToMany(targetEntity="Children", mappedBy="beauties")
     **/
    private $children;
    public function __construct()
    {
        $this->children = new ArrayCollection();
    }


    /**
    * @ORM'Column(type="integer")
    * @ORM'Id
    * @ORM'GeneratedValue(strategy="AUTO")
    */
    protected $id;
    /**
    * @ORM'Column(type="string", length=100)
    */
    protected $name;
    /**
    * @ORM'Column(type="text")
    */
    protected $content;  

    /**
     * @Vich'UploadableField(mapping="beauty_image", fileNameProperty="imageName")
     * @var File $imageFile
     */
    protected $imageFile;
    /**
     * @ORM'Column(type="string", length=255, nullable=true, name="image_name")
     * @var string $imageName
     */
    protected $imageName;

    /**
    * @ORM'ManyToOne(targetEntity="Category", inversedBy="beauties")
    * @ORM'JoinColumn(name="category_id", referencedColumnName="id")
    */
    protected $category;


/**
     * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
     * of 'UploadedFile' is injected into this setter to trigger the  update. If this
     * bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
     * must be able to accept an instance of 'File' as the bundle will inject one here
     * during Doctrine hydration.
     *
     * @param File|'Symfony'Component'HttpFoundation'File'UploadedFile
     */
    public function setImageFile(File $image = null)
    {
        $this->imageFile = $image;
        if ($image) {
            // It is required that at least one field changes if you are using doctrine
            // otherwise the event listeners won't be called and the file is lost
            $this->updatedAt = new 'DateTime('now');
        }
    }
    /**
     * @return File
     */
    public function getImageFile()
    {
        return $this->imageFile;
    }
    /**
     * @param string $imageName
     */
    public function setImageName($imageName)
    {
        $this->imageName = $imageName;
    }
    /**
     * @return string
     */
    public function getImageName()
    {
        return $this->imageName;
    }



    public function __toString()
    {
    return ($this->getName()) ? : '';
    }
    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }
    /**
     * Set name
     *
     * @param string $name
     * @return Beauty
     */
    public function setName($name)
    {
        $this->name = $name;
        return $this;
    }
    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }
    /**
     * Set content
     *
     * @param string $content
     * @return Beauty
     */
    public function setContent($content)
    {
        $this->content = $content;
        return $this;
    }
    /**
     * Get content
     *
     * @return string 
     */
    public function getContent()
    {
        return $this->content;
    }
    /**
     * Set category
     *
     * @param 'Beautify'BeautiesBundle'Entity'Category $category
     * @return Beauty
     */
    public function setCategory('Beautify'BeautiesBundle'Entity'Category $category = null)
    {
        $this->category = $category;
        return $this;
    }
    /**
     * Get category
     *
     * @return 'Beautify'BeautiesBundle'Entity'Category 
     */
    public function getCategory()
    {
        return $this->category;
    }

    /**
     * Set children
     *
     * @param 'Beautify'BeautiesBundle'Entity'Children $children
     * @return Beauty
     */
    public function setChildren('Beautify'BeautiesBundle'Entity'Children $children = null)
    {
        $this->children = $children;
        return $this;
    }
    /**
     * Get children
     *
     * @return 'Beautify'BeautiesBundle'Entity'Children 
     */
    public function getChildren()
    {
        return $this->children;
    }


    /**
     * Add children
     *
     * @param 'Beautify'BeautiesBundle'Entity'Children $children
     * @return Beauty
     */
    public function addChild('Beautify'BeautiesBundle'Entity'Children $children)
    {
        $this->children[] = $children;
        return $this;
    }
    /**
     * Remove children
     *
     * @param 'Beautify'BeautiesBundle'Entity'Children $children
     */
    public function removeChild('Beautify'BeautiesBundle'Entity'Children $children)
    {
        $this->children->removeElement($children);
    }
}

子.php实体


<?php

namespace Beautify'BeautiesBundle'Entity;
use Doctrine'ORM'Mapping as ORM;

/**
 * Children
 *
* @ORM'Table(name="children")
 * @ORM'Entity
 */
class Children
{
    /**
     * @ORM'ManyToOne(targetEntity="Beauty", inversedBy="children")
     * @ORM'JoinColumn(name="beauty_id", referencedColumnName="id")
     **/
    private $beauties;

    /**
     * @var integer
     *
     * @ORM'Column(name="id", type="integer")
     * @ORM'Id
     * @ORM'GeneratedValue(strategy="AUTO")
     */
    private $id;
    /**
     * @var string
     *
     * @ORM'Column(name="image", type="string", length=255)
     */
    private $image;
    /**
     * @var string
     *
     * @ORM'Column(name="content", type="text")
     */
    private $content;
    /**
     * @var integer
     *
     * @ORM'Column(name="priority", type="integer")
     */
    private $priority;
    /**
     * @var integer
     *
     * @ORM'Column(name="parent_id", type="integer")
     */
    private $parentId;

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }
    /**
     * Set image
     *
     * @param string $image
     * @return Children
     */
    public function setImage($image)
    {
        $this->image = $image;
        return $this;
    }
    /**
     * Get image
     *
     * @return string 
     */
    public function getImage()
    {
        return $this->image;
    }
    /**
     * Set content
     *
     * @param string $content
     * @return Children
     */
    public function setContent($content)
    {
        $this->content = $content;
        return $this;
    }
    /**
     * Get content
     *
     * @return string 
     */
    public function getContent()
    {
        return $this->content;
    }
    /**
     * Set priority
     *
     * @param integer $priority
     * @return Children
     */
    public function setPriority($priority)
    {
        $this->priority = $priority;
        return $this;
    }
    /**
     * Get priority
     *
     * @return integer 
     */
    public function getPriority()
    {
        return $this->priority;
    }
    /**
     * Set parentId
     *
     * @param integer $parentId
     * @return Children
     */
    public function setParentId($parentId)
    {
        $this->parentId = $parentId;
        return $this;
    }
    /**
     * Get parentId
     *
     * @return integer 
     */
    public function getParentId()
    {
        return $this->parentId;
    }


    /**
     * Set beauties
     *
     * @param 'Beautify'BeautiesBundle'Entity'Beauty $beauties
     * @return Children
     */
    public function setBeauties('Beautify'BeautiesBundle'Entity'Beauty $beauties = null)
    {
        $this->beauties = $beauties;
        return $this;
    }
    /**
     * Get beauties
     *
     * @return 'Beautify'BeautiesBundle'Entity'Beauty 
     */
    public function getBeauties()
    {
        return $this->beauties;
    }
}

非常感谢任何帮助...

错误说明了一切。您需要将 cascade="persist" 添加到 child 属性。

/**
 * @ORM'OneToMany(targetEntity="Children", mappedBy="beauties", cascade={"persist"})
 **/
private $children;

见 http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-associations.html#transitive-persistence-cascade-operations