Description
We have been experiencing an intermittent issue where entries into the url_rewrite table are not being generated automatically. I have noticed that this issue has been mentioned in the past but I believe that we have isolated the cause.
Magento\UrlRewrite\Model\Storage\DbStorage::doReplace(...) doesn't do a REPLACE but an INSERT, and errors for duplicate entries aren't throwing an AlreadyExistsException as expected.
A general gist of the code path is as follows:
Magento\CatalogUrlRewrite\Model\UrlRewriteBunchReplacer::doBunchReplace(...) ->
Magento\UrlRewrite\Model\Storage\DbStorage::doReplace(...) ->
Magento\Framework\DB\Adapter\Pdo\Mysql::insertMultiple(...) ->
Magento\Framework\DB\Adapter\Pdo\Mysql::insertArray(...)
When we updated the doReplace(...) and insertMultiple(...) functions to pass the replace strategy through to insertArray(...) everything worked as expected. Would I be correct in assuming that this was the intended strategy and that is was just missing from doReplace and insertMultiple? Why would it not be a replace?
Also, any calls to Magento\Framework\DB\Adapter\Pdo\Mysql::insertMultiple(...) will fail if there are duplicates in the data based on unique constraints. This function doesn't take this into account and doesn't have the ability to pass the strategy through to insertArray(...). There also doesn't appear to be an equivalent replaceMultiple(...).
I would guess that this might be causing some other bugs we have noticed, particularly with importing catalog data from a CSV.
Preconditions
- Magento 2.2.5
- PHP 7.1.20
- MySQL 5.7.23
- Multiple stores set up and enabled with the same products and root category
Steps to reproduce
Assuming that the category data will fail for a duplicate entry:
- Update the URL key for a category
Actual result
Received the following MySQL error running the query that Magento genereted:
Error Code: 1062. Duplicate entry 'some-product-1' for key 'URL_REWRITE_REQUEST_PATH_STORE_ID'
An AlreadyExistsException didn't appear to have been thrown, or was silently handled.
Expected result
The correct entries in the url_rewrite table are created.