如何使用许多相关对象持久化一个对象

Cze*_*ogy 6 php symfony doctrine-orm

我有实体BasketBasketItem:

/**
 * Acme\BasketBundle\Entity\Basket
 *
 * @ORM\Entity(repositoryClass="Acme\BasketBundle\Repository\BasketRepository")
 * @ORM\Table(name="orders")
 * @ORM\HasLifecycleCallbacks()
 */
class Basket
{
  /**
   * @var integer $id
   *
   * @ORM\Column(name="id", type="integer")
   * @ORM\Id
   * @ORM\GeneratedValue(strategy="AUTO")
   */
  private $id;

  // ...

  /**
    * @ORM\OneToMany(targetEntity="BasketItem", mappedBy="order_id",cascade={"all"})
    */
  protected $items;

  // ...

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

  /**
   * Add item
   *
   * @param BasketItem $item
   */
  public function addItem(BasketItem $item)
  {
    $key = $this->find($item->getProduct()->getId());

    if ($key === false) {
        $this->items->add($item);
    } else {
        $this->items->get($key)->raiseQuantity($item->getQuantity());
    }
  }

  /**
   * Find an item (if present)
   *
   * @param integer $id
   * @return integer
   */
  public function find($id)
  {
    foreach ($this->items as $key => $item) {
        if ($item->getProduct()->getId() == $id)
            return $key;
    }
    return false;
  }
}
Run Code Online (Sandbox Code Playgroud)


/**
 * Acme\BasketBundle\Entity\BasketItem
 *
 * @ORM\Entity
 * @ORM\Table(name="order_items")
 */
class BasketItem
{
  /**
   * @var integer $id
   *
   * @ORM\Column(name="id", type="integer")
   * @ORM\Id
   * @ORM\GeneratedValue(strategy="AUTO")
   */
  private $id;

  // ...

  /**
   * @ORM\ManyToOne(targetEntity="Basket", inversedBy="items")
   * @ORM\JoinColumn(name="order_id", referencedColumnName="id")
   */
  private $basket;

  // ...
}
Run Code Online (Sandbox Code Playgroud)

现在,当我创建一个篮子并用项目填充它时,我很难将其持久保存到数据库中.

以下不能按预期工作.

$basket = new Basket();
$basket->addItem(new BasketItem($product1, 1));
$basket->addItem(new BasketItem($product2, 2));

$em->persist($basket);
$em->flush();
Run Code Online (Sandbox Code Playgroud)

然后我尝试更仔细地遵循手册:

$basket = new Basket();
$basket->addItem(new BasketItem($product1, 1));
$basket->addItem(new BasketItem($product2, 2));

$em->persist($basket);
foreach ($basket->getItems() as $item) {
    $em->persist($item);
}
$em->flush();
Run Code Online (Sandbox Code Playgroud)

这没有预期的效果.

在这两种情况下,所有的数据被保存到数据库中,但篮下的项目不涉及到篮下,即order_id在的BasketItem实体NULL.

谁能解释一下我做错了什么,拜托?请注意我是Doctrine的新手.谢谢!




编辑:

我已经很困惑了.这是我的简化测试:

<?php

namespace Amsel\BasketBundle\Entity;

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

/**
 * Amsel\BasketBundle\Entity\Basket
 *
 * @ORM\Entity(repositoryClass="Amsel\BasketBundle\Repository\BasketRepository")
 * @ORM\Table(name="orders")
 */
class Basket
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var ArrayCollection $items
     *
     * @ORM\OneToMany(targetEntity="BasketItem", mappedBy="basket", cascade={"all"})
     */
    protected $items;

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

    /**
     * Add item
     *
     * @param BasketItem $item
     */
    public function addItem(BasketItem $item)
    {
        $this->items->add($item);
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Get items
     *
     * @return Doctrine\Common\Collections\Collection 
     */
    public function getItems()
    {
        return $this->items;
    }
}
Run Code Online (Sandbox Code Playgroud)


<?php

namespace Amsel\BasketBundle\Entity;

use Doctrine\ORM\Mapping as ORM;


/**
 * Amsel\BasketBundle\Entity\BasketItem
 *
 * @ORM\Entity(repositoryClass="Amsel\BasketBundle\Repository\BasketItemRepository")
 * @ORM\Table(name="order_items")
 */
class BasketItem
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var Basket $basket
     *
     * @ORM\ManyToOne(targetEntity="Basket", inversedBy="items")
     * @ORM\JoinColumn(name="order_id", referencedColumnName="id")
     */
    protected $basket;


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set basket
     *
     * @param Amsel\BasketBundle\Entity\Basket $basket
     */
    public function setBasket(\Amsel\BasketBundle\Entity\Basket $basket)
    {
        $this->basket = $basket;
    }

    /**
     * Get basket
     *
     * @return Amsel\BasketBundle\Entity\Basket 
     */
    public function getBasket()
    {
        return $this->basket;
    }
}
Run Code Online (Sandbox Code Playgroud)


public function testAction(Request $request) {

    $em = $this->getDoctrine()->getEntityManager();

    $basket = new Basket();
    $basket->addItem(new BasketItem());
    $basket->addItem(new BasketItem());

    $em->persist($basket);

    try {
        $em->flush();
    } catch(Exception $e) {
        die('ERROR: '.$e->getMessage());
    }        
    die ('end');
}
Run Code Online (Sandbox Code Playgroud)

但仍然 - 订单items(BasketItem)被存储但没有链接到订单(Basket).

Cze*_*ogy 3

如果我正确理解系统,我还必须 - 因为它是双向关系 - 手动将父Basket实体分配给每个BasketItem实体。

public function testAction(Request $request) {

    $em = $this->getDoctrine()->getEntityManager();

    $basket = new Basket();

    $bi1 = new BasketItem();
    $bi1->setBasket($basket);

    $bi2 = new BasketItem();
    $bi2->setBasket($basket);

    $basket->addItem($bi1);
    $basket->addItem($bi2);

    $em->persist($basket);

    try {
        $em->flush();
    } catch(Exception $e) {
        die('ERROR: '.$e->getMessage());
    }        
    die ('end');
}
Run Code Online (Sandbox Code Playgroud)

像这样工作得很好,但如果我走错了路,请纠正我。

感谢所有花时间看我的问题的人!