4

I'm a bit puzzled about how the load() and objectManager are different. I have a model where I inject the order model to load an order by it's ID, then I use the order to get its shipments:

public function __construct(Magento\Sales\Model\Order $order) {
  $this->_order = $order;
}

public function getShipment($oid) {
  $order = $this->_order->load($oid);
  // I always have only one shipment per order so I can call directly the firstItem method
  $shipment = $order->getShipmentsCollection()->getFirstItem();
}

The problem with this code is this:

$this->_order->load($oid);
calls the order correctly (if I pass the id 32, then it loads the order with id 32, if I pass the id 33, then it loads the order with id 33 and so on), but
$shipment = $order->getShipmentsCollection()->getFirstItem();
calls always the same shipment, so no matter if the order loaded is 31, 32, 33 etc etc the shipment returned is always the same (eg: shipment with id 20).

If I substitute

$this->_order->load($oid);
with the objectManager
$order = $objectManager->create('\Magento\Sales\Model\Order')->load($oid);
then the shipment returned is correct, so for order 31 I get shipment 20, for order 32 I get the shipment 21 and so on.

Why does the load() method always return the same shipment on different orders?

1

The difference between $this->_order->load($oid) and $objectManager->create('\Magento\Sales\Model\Order')->load($oid) is that the former uses the same Order object and the latter creates a new one each time.

I suspect the reason why getShipmentsCollection() returns the shipments collection of the first order every time, is simply that the order model caches the collection. If you create a new model, no cache is present.

Loading an entity via a model is a Magento 1 style. The Magento 2 way is to use a repository from the Api:

use Magento\Sales\Api\OrderRepositoryInterface;

/**
 * @var OrderRepositoryInterface
 */
protected $orderRepository;

public function __construct(
    OrderRepositoryInterface $orderRepository
)
{
    $this->orderRepository = $orderRepository;
}

public function getShipment($oid) {
    $order = $this->orderRepository->get($oid);

    // I always have only one shipment per order so I can call directly the firstItem method
    $shipment = $order->getShipmentsCollection()->getFirstItem();
    return $shipment;
}
  • "Loading an entity via a model is a Magento 1 style. The Magento 2 way is to use a repository from the Api" you are right. The problem I find with the repository is that they throw errors instead of letting you try/catch them. So if I use $this->orderRepository->get($oid) then the code throws errors if it doesn't find the $oid I'm looking for and the execution stops. With model I'm able to manage code and errors better. Anyway, I understand about cache, thank you very much for your explanation, it was very clear – Lounik Aug 3 '18 at 12:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.