【问题标题】:entityManager save and refreshentityManager 保存和刷新
【发布时间】:2012-02-20 11:13:44
【问题描述】:

我正在尝试以级联方式保存一些对象并检索它。 我有 3 个对象超过 3 个实体。

实体:

class Order
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var object $basket
     *
     * @ORM\OneToOne(targetEntity="Entity\Basket", inversedBy="order")
     */
    protected $basket;
...
}

class Basket
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var array $declinations
     *
     * @ORM\OneToMany(targetEntity="Entity\BasketDeclination", mappedBy="basket")
     */
    protected $declinations;

    /**
     * Order owner (reversed side)
     * 
     * @var OrderClient $order
     * 
     * @ORM\OneToOne(targetEntity="Entity\Order", mappedBy="basket")
     */
    protected $order;
...
}

class BasketDeclination
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var integer $basket
     *
     * @ORM\ManyToOne(targetEntity="Entity\Basket", inversedBy="declinations")
     */
    protected $basket;
...
}

对象优于实体:

class OrderObject
{
    function __construct(
        EntityManager $em,
        Order $entity = null,
        BasketObject $basket = null
    )
    {
        $this->em = $em;

        if (!$entity) {
            $this->entity = new Order();

            $this->basket = $basket;
        } else {
            $this->setDataFromEntity($entity);
        }
    }

    protected function setDataFromEntity(Order $entity)
    {
        $basketFactory = new BasketFactory($this->em);

        $this->entity = $entity;

        $this->basket = $basketFactory->getBasket($entity->getBasket()->getId());
    }

    public function save($flush = false)
    {
        // save subObject
        $this->basket->save();

        // set link
        $this->entity->setBasket($this->basket->getEntity());

        $this->em->persist($this->entity);

        if ($flush) {
            $this->em->flush();
        }
    }

    public function refresh()
    {
        $this->em->refresh($this->entity);
        $this->setDataFromEntity($this->entity);
    }
...
}

class BasketObject
{
    function __construct(EntityManager $em, Basket $entity = null)
    {
        $this->em = $em;

        if (!$entity) {
            $this->entity = new Basket();
            $this->declinations = array();
        } else {
            $this->setDataFromEntity($entity);
        }
    }

    protected function setDataFromEntity(Basket $entity)
    {
        $this->entity = $entity;

        $this->declinations = array();
        foreach ($entity->getDeclinations() as $declination) {
            $this->declinations[] = new BasketDeclinationObject($this->em, $declination);
        }
    }

    public function save($flush = false)
    {
        foreach ($this->declinations as $declination) {
            $declination->save();
        }
        $this->em->persist($this->entity);
        if ($flush) {
            $this->em->flush();
        }
    }
...
}

class BasketDeclinationObject
{
    public function __construct(
            EntityManager $em,
            BasketDeclination $entity= null,
            BasketObject $basket = null)
    {
        $this->em = $em;

        if (!$entity) {
            $this->entity = new BasketDeclination();

            $this->basket = $basket;
        } else {
            $this->setDataFromEntity($entity);
        }
    }

    protected function setDataFromEntity(BasketDeclination $entity)
    {
        $this->entity = $entity;

        $declinationFactory = new DeclinationFactory($this->em);
        $this->declination = $declinationFactory->getDeclination($entity->getDeclination()->getId());
    }

    public function save($flush = false)
    {
        if ($this->quantity <= 0) {
            $this->em->remove($this->entity);
            $this->remove = true;
            return ;
        }
        if (!$this->entity->getId()) {
            $this->entity->setBasket($this->basket->getEntity());
        }
        $this->entity->setQuantity($this->quantity);
        $this->em->persist($this->entity);
        if ($flush) {
            $this->em->flush();
        }
    }
...
}

问题是,在我的测试中,当我尝试一个篮子添加 BasketDeclination 然后保存 篮子被保存,篮子偏角也被保存。 然后当我 $basket->refresh() 时,篮子被刷新并且 BasketDeclinaiton 是从实体重建的

但是当我有一个带有篮子的订单并添加 BasketDeclinaiton ($order->basket->addDeclination(...)) 当我保存所有实体时 然后当我刷新订单时,我会取回订单和购物篮。 但是实体 $basket->getDeclilations() 没有任何东西

我做错了什么?

【问题讨论】:

  • 这纯粹是在黑暗中拍摄:尝试在刷新之前调用 $entityManager()->clear()。你有太多的东西和事情要我可怜的大脑去追随。您也可以考虑发布一个非常简单的测试用例来显示问题。
  • 一点...对于You have way too many objects and things going on for my poor brain to follow

标签: symfony doctrine-orm entitymanager


【解决方案1】:

如果问题确实是实体管理器不是refreshing 关联(如Mohammad AbuShady 所建议的那样),则告诉您的实体级联refresh 操作的答案。

class Basket
{
    // ... 

    /**
     * @var array $declinations
     *
     * @ORM\OneToMany(
     *   targetEntity="Entity\BasketDeclination", 
     *   mappedBy="basket",
     *   cascade={"refresh"}    // THIS LINE ADDED
     * )
     */
    protected $declinations;

    // ...
...
}

【讨论】:

    【解决方案2】:

    我会猜测两个:

    • 您应该对类使用级联注释以允许级联“持久”并且可能也级联“刷新”。如documentation 所述。比如:

      @ORM\OneToOne(targetEntity="Entity\Order", mappedBy="basket", cascade={"persist", "remove", "refresh"})

    • 在刷新之前,您在 Declinations 上缺少 persist()flush()。如果您没有级联,则需要在要保留的每个对象上调用它们,然后调用 refresh() 方法。

    (当您使用嵌套对象时,检查您的代理是否已创建并正常工作也是一个好主意)

    【讨论】:

      【解决方案3】:

      我记得从教义1,不确定是否同样适用,在教义1刷新只刷新第一个直接对象,处理关系和你需要添加第二个参数deep = true来处理所有相关对象的东西,您可以尝试研究类似的内容。

      【讨论】:

      • EntityManager-&gt;refresh()method here没有第二个参数
      • 好吧,这让我有点困惑,但是为什么你在 refresh 函数中没有一个 $this-&gt;em-&gt;refresh($this-&gt;basket);
      猜你喜欢
      • 2011-08-15
      • 2022-10-07
      • 2011-01-05
      • 2013-02-11
      • 2012-04-19
      • 2022-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多