Description
This issue is automatically created based on existing pull request: #29579: Fix ability to query bulk operations across multiple bulk_uuid values (broken by 2.4 release)
Description (*)
The 2.4 release broke our ability to query Bulk Operations by status or start_date. Any attempt to do so causes an exception response:
"Item (Magento\\AsynchronousOperations\\Model\\Operation) with the same ID \"0\" already exists.",
Steps to Recreate
POST two bulk loads into Magento REST - confirm that two magento_bulk records are created, and magento_operation records (depending on number of items in the bulk load). You'll see that for each bulk_uuid, the operation_key is sequential, e.g:
<first_bulk_uuid>, 0
<first_bulk_uuid>, 1
<first_bulk_uuid>, 2
...
<second_bulk_uuid>, 0
<second_bulk_uuid>, 1
<second_bulk_uuid>, 2
...
Query the operations via
/rest/V1/bulk/?searchCriteria[filter_groups][0][filters][0][field]=status&searchCriteria[filter_groups][0][filters][0][value]=1&searchCriteria[filter_groups][0][filters][0][condition_type]=eq"
(change the status
filter value to suit your message status, as long as there are two messages with the same operation_key and same status)
Receive the noted exception response.
Root Cause
\Magento\Framework\Data\Collection\AbstractDb::loadWithFilter
=> \Magento\Framework\Data\Collection::addItem
=> \Magento\Framework\Data\Collection::_getItemId
=> \Magento\AsynchronousOperations\Model\Operation::getId
In 2.4, the getId method of the Operation model was (incorrectly IMO) changed to return the operation_key
value. But the operation_key
is NOT a unique value - I believe that should have been added as a new field on the model, and that the existing ID field (mirroring the SQL autoincrement unique value) remains used for the array index when building the collection:
public function addItem(DataObject $item)
{
$itemId = $this->_getItemId($item);
if ($itemId !== null) {
if (isset($this->_items[$itemId])) {
//phpcs:ignore Magento2.Exceptions.DirectThrow
throw new \Exception(
'Item (' . get_class($item) . ') with the same ID "' . $item->getId() . '" already exists.'
);
}
$this->_items[$itemId] = $item;
} else {
$this->_addItem($item);
}
return $this;
}
Contribution checklist (*)
- Pull request has a meaningful description of its purpose
- All commits are accompanied by meaningful commit messages
- All new or changed code is covered with unit/integration tests (if applicable)
- [TBC] All automated tests passed successfully (all builds are green)
Metadata
Assignees
Labels
Type
Projects
Status
Done