[PR #6358] ObjectHydrator: fixed initialization of left joined collections #9947

Closed
opened 2026-01-22 16:05:57 +01:00 by admin · 0 comments
Owner

Original Pull Request: https://github.com/doctrine/orm/pull/6358

State: closed
Merged: No


There is initialization of collections which are considered to be empty and are not fetched twice from commit 3407620bf8.

But implementation is wrong, it decided collection to be empty from first row only. If there were data in next row collection was already initialized. So it all ended with empty related collections marked as initialized.

How to replicate bug:

  1. I have selected 10 Orders
SELECT base FROM Orders\Order base
  1. Pre fetched all products for these orders (which are ManyToMany)
	/**
	 * @ORM\ManyToMany(targetEntity="Product\Item", fetch="EXTRA_LAZY", indexBy="id")
	 * @ORM\JoinTable(name="orders_items",
	 *    joinColumns={@ORM\JoinColumn(name="order_id", referencedColumnName="id")},
	 *    inverseJoinColumns={@ORM\JoinColumn(name="productItem_id", referencedColumnName="id")}
	 * )
	 * @var Product\Item[]
	 */
	protected $productItems;
SELECT partial base.{id}, productItems FROM Orders\Order base LEFT JOIN base.productItems productItems WHERE base.id IN('1840452', '1840448', '1840442', '1840420', '1840400', '1840394', '1840372', '1840348', '1840340', '1840332')

data

where id_0 is order id and id_1 product item id

  1. Now collections were empty
count($order->productItems); //resulted in 0

because every collection was marked as initialized while hydrating first row which had no data.

While hydrating rows with data, it didn`t passed through condition in \Doctrine\ORM\Internal\Hydration\ObjectHydrator::initRelatedCollection

            isset($this->_hints[Query::HINT_REFRESH]) ||
            isset($this->_hints['fetched'][$parentDqlAlias][$fieldName]) &&
             ! $value->isInitialized()
**Original Pull Request:** https://github.com/doctrine/orm/pull/6358 **State:** closed **Merged:** No --- There is initialization of collections which are considered to be empty and are not fetched twice from commit https://github.com/doctrine/doctrine2/commit/3407620bf80ec5d09475dcab1f0e089aecfcc064. But implementation is wrong, it decided collection to be empty from first row only. If there were data in next row collection was already initialized. So it all ended with empty related collections marked as initialized. How to replicate bug: 1. I have selected 10 Orders ```sql SELECT base FROM Orders\Order base ``` 2. Pre fetched all products for these orders (which are ManyToMany) ```php /** * @ORM\ManyToMany(targetEntity="Product\Item", fetch="EXTRA_LAZY", indexBy="id") * @ORM\JoinTable(name="orders_items", * joinColumns={@ORM\JoinColumn(name="order_id", referencedColumnName="id")}, * inverseJoinColumns={@ORM\JoinColumn(name="productItem_id", referencedColumnName="id")} * ) * @var Product\Item[] */ protected $productItems; ``` ```sql SELECT partial base.{id}, productItems FROM Orders\Order base LEFT JOIN base.productItems productItems WHERE base.id IN('1840452', '1840448', '1840442', '1840420', '1840400', '1840394', '1840372', '1840348', '1840340', '1840332') ``` ![data](https://cloud.githubusercontent.com/assets/4031169/24307241/a4b3ea5a-10c3-11e7-8993-29c79ba2f3f2.png) where id_0 is order id and id_1 product item id 3. Now collections were empty ```php count($order->productItems); //resulted in 0 ``` because every collection was marked as initialized while hydrating first row which had no data. While hydrating rows with data, it didn`t passed through condition in \Doctrine\ORM\Internal\Hydration\ObjectHydrator::initRelatedCollection ```php isset($this->_hints[Query::HINT_REFRESH]) || isset($this->_hints['fetched'][$parentDqlAlias][$fieldName]) && ! $value->isInitialized() ```
admin added the pull-request label 2026-01-22 16:05:57 +01:00
admin closed this issue 2026-01-22 16:05:57 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#9947