entityManager сохранить и обновить - PullRequest
4 голосов
/ 20 февраля 2012

Я пытаюсь сохранить в каскаде какой-нибудь объект и получить его.У меня есть 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, затем сохранить корзину, сохраненную и BasketDeclination тоже.Затем, когда я $ basket-> refresh (), корзина обновляется, и BasketDeclinaiton перестраивается из сущности

НО, когда у меня есть заказ с корзиной, и я добавляю BasketDeclinaiton ($ order-> basket-> addDeclination (...)) Когда я сохраняю, все сущности сохраняются, затем, когда я обновляю заказ, я возвращаю заказ и корзину.но сущность $ basket-> getDeclinations () не имеет ничего

Что я делаю не так?

Ответы [ 3 ]

0 голосов
/ 20 февраля 2015

Если проблема действительно в том, что менеджер сущностей не refresh связывает (как предложено Мохаммад АбуШади ), ответ, чтобы сказать вашим сущностям каскадную операцию refresh.

class Basket
{
    // ... 

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

    // ...
...
}
0 голосов
/ 25 января 2017

Я пойду с двумя догадками:

  • Вы должны использовать каскадную аннотацию к классам, чтобы позволить каскаду "сохраняться" и, возможно, каскаду "обновлять" тоже. Как указано в документации . Что-то вроде:

    @ ORM \ OneToOne (targetEntity = "Entity \ Order", mappedBy = "корзина", cascade = {"persist", "remove", "refresh"})

  • Вам не хватает persist() или flush() на склонениях перед обновлением. Если вы не каскадируете, вам нужно вызывать их для каждого объекта, который вы хотите сохранить, а затем вызывать метод refresh().

(Это также хорошая идея, чтобы проверить, что ваши прокси созданы и работают нормально, когда вы работаете с вложенными объектами)

0 голосов
/ 02 июня 2013

Я помню это из doctrine1, не уверенный, применимо ли то же самое и здесь, в doctrine1 при обновлении обновляется только первый прямой объект, для обработки отношений и прочего вам нужно добавить второй параметр deep = true для обработки всех связанных объектов.Вы можете попробовать что-то подобное.

...