0

我还不能在 Symfony2 中正确配置关联。对于一对多关系(许多家庭成员到一个客户),当前代码显示在下面。
当成员 foreach 循环被省略时,客户端按预期添加。目前的错误是:

通过关系“Mana\ClientBundle\Entity\Client#members”找到了一个新实体,该关系未配置为对实体进行级联持久化操作:Mana\ClientBundle\Entity\Member@00000000248e5b80000000004cc2e70f。要解决这个问题:要么在这个未知实体上显式调用 EntityManager#persist(),要么配置级联在映射中保持此关联,例如 @ManyToOne(..,cascade={"persist"})。如果您无法找出导致问题的实体,请执行“Mana\ClientBundle\Entity\Member#__toString()”以获取线索。

客户端实体片段

namespace Mana\ClientBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * Mana\ClientBundle\Entity\Client
 *
 * @ORM\Table(name="client")
 * @ORM\Entity
 */
class Client
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
    * @ORM\OneToMany(targetEntity="Mana\ClientBundle\Entity\Member", mappedBy="client")
    */
    protected $members;

    public function __construct()
    {
        $this->members = new ArrayCollection();
    }

    public function setMembers(ArrayCollection $members)
    {
        $this->members = $members;
        return $this;
    }

    public function addMember(Member $member)
    {
        $this->members->add($member);
        return $this;
    }

    public function removeMember(Member $member)
    {
        $this->members->removeElement($member);
        return $this;
    }

    public function getMembers()
    {
        return $this->members;
    }

家庭实体

namespace Mana\ClientBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Mana\ClientBundle\Entity\Member
 *
 * @ORM\Table(name="household")
 * @ORM\Entity
 */
class Member
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

     /**
     * @ORM\ManyToOne(targetEntity="Client", inversedBy="members")
     * @ORM\JoinColumn(name="clientId", referencedColumnName="id")
     *
     */
     protected $client;

//--- properties

    public function setClient(Client $client)
    {
        $this->client = $client;
        return $this;
    }

    public function getClient()
    {
        return $this->client;
    }

//  getters, setters

控制器 createAction():

    public function createAction(Request $request)
    {
        $client  = new Client();
        $form = $this->createForm(new ClientType(), $client);
        $form->bind($request);

        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($client);
            $em->flush();
            foreach ($client->getMembers() as $member)
            {
                $em->persist($member);
            }
            $em->flush();
            return $this->redirect($this->generateUrl('client_show', array('id' => $entity->getId())));
        }
4

3 回答 3

0

“$members”包含什么?

您得到的错误是您基本上是在尝试在数据库中存储一些具有“client_id”的对象,但不是由您的对象设置。

如果 $members 包含的任何内容都有该列,则可能是您需要调用类似

$member->setClient($entity) 

在您尝试刷新()它们之前。

此外,您知道,在实际调用 $em->flush() 之前不会抛出该错误,因为这是它尝试将某些内容插入数据库的唯一时间。它很可能在没有 for 循环的情况下工作,因为 $members 从未添加到客户端,因此它不会尝试持久化它们。

更新

您不应该直接分配客户端 ID。你的第一次关系更正确。

// In HouseHold
/**
 *@ORM\ManyToOne(targetEntity="Client")
 *@ORM\JoinColumn(name="clientId", referencedColumnName="id")
 */
protected $client;

public function getClient() { return $this->client; }
public function setClient(Client $client) { $this->client = $client; }

比 $member->setClient($client) 代替 setClientId()。

就 Doctrine 而言,clientId 变量对它没有任何意义。它正在客户端上寻找 getClientId()。

于 2012-12-08T21:41:10.340 回答
0

要认识到的基本因素是,Doctrine 仅作用于对多对一关系的拥有方所做的更改,而拥有方是包含多对一子句的实体。因此,对于目前的情况,家庭是需要坚持的拥有方,而不是客户。所以控制器的关键变化是:

    $member->setClient($client);
    $em->persist($member);
于 2012-12-09T17:48:34.210 回答
0

您可以使用

foreach ($client->getMembers() as $member)
        {
            $em->merge($member);
        }
于 2014-12-24T00:27:52.123 回答