I'm stuck with a specific scenario regarding Aggregates and not breaking business invariants.
I've two entities, let's call them Order and OrderItem. Both entities belong to an aggregate with Order as Aggregate root.
When I need to update one specific OrderItem I do it through the Aggregate root:
class Order
{
private Collection $orderItems;
public function __construct()
{
$this->orderItems = new Collection;
}
public function updateOrderItemPrice(OrderItemId $id, int $newPrice): void
{
foreach ($this->orderItems as $orderItem) {
if ($orderItem->id()->equals($id) {
$orderItem->updatePrice($newPrice);
break;
}
}
}
}
While this solution works fine for small collections, it can lead to a huge performance penalty when we're talking about thousands (or tens of thousands) of records due the ORM (Doctrine in my case) will try to load all the order items in memory when you're about to iterate it.
Is there any pattern or good practice to solve this specific scenario?