Christopher Francisco
Christopher Francisco

Reputation: 16278

Doctrine 2 ArrayCollection::add() persists items in reverse order

I'm making multiple calls to $this->myDependentEntityCollection[] = $myDependentEntity; (being it a type of ArrayCollection or PersistentCollection before calling persist() and flush() on the independent entity (using cascade=persist).

However, the dependent entities in the collection are being persisted in the reverse order than the one they're added (I'm guessing they use a stack, then pop items one by one).

Take the following example for a Order and Item with a 1:N relationship:

// Order.php
/* (...doctrine stuff...,  cascade={"persist"}) */
protected $items;

public function addItem(Item $item) {
    $item->setOrder($this);
    $this->items[] = $item;
}

// Item.php
public function setOrder(Order $order) {
   $this->order = $order;
}

// Somewhere else in the code
$order->addItem($item1);
$order->addItem($item2);
$order->addItem($item3);

$em->persist($order);
$em->flush();

They get persisted in the order item3, item2, item1; rather than 1,2,3.

How can I make it so that they get saved in the correct order?

Upvotes: 3

Views: 1757

Answers (1)

Matteo
Matteo

Reputation: 39390

Try using array_unshift:

array_unshift — Prepend one or more elements to the beginning of an array

as example:

public function addItem(Item $item) {
    $item->setOrder($this);
    array_unshift($this->items, $item);
}

Hope this help

NOTE:

As in the comment Christopher Francisco say, is not possibile to pass a ArrayCollection object to the array_unshift function, so a trick can be the following:

public function addItem(Item $item) {
    $item->setOrder($this);
    $itemsAsArray = $this->items->toArray();
    array_unshift($itemsAsArray, $item);
    $this->items = new ArrayCollection($itemsAsArray);
}

Otherwise, you could implement a method on the object that inverse the order of the array and call it before persisting, but is more error prone (You could forgot to call the method).

Upvotes: 3

Related Questions