diff --git a/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php b/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php index 505bc031311..ff3a90fa65f 100644 --- a/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php +++ b/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php @@ -173,7 +173,7 @@ public function getMediaEntries(array $images): array */ public function addChild($sku, $childSku) { - $product = $this->productRepository->get($sku, true); + $product = $this->productRepository->get($sku, true, null, true); $child = $this->productRepository->get($childSku); $childrenIds = array_values($this->configurableType->getChildrenIds($product->getId())[0]); diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php index ded4fd10b8d..fe1dd80cdfa 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php @@ -228,6 +228,42 @@ public function testAddChild(): void $this->assertTrue($this->object->addChild($productSku, $childSku)); } + public function testAddChildLoadsParentWithForceReload(): void + { + $productSku = 'configurable-sku'; + $childSku = 'simple-sku'; + + $configurable = $this->createMock(Product::class); + $configurable->method('getId')->willReturn(666); + $simple = $this->createMock(Product::class); + $simple->method('getId')->willReturn(1); + + // Assert that the parent is loaded with forceReload=true (4th argument) + // to bypass the in-memory cache. This prevents stale data from being used + // in long-lived processes such as queue consumers. + $this->productRepository + ->expects($this->atLeastOnce()) + ->method('get') + ->willReturnCallback( + function ($sku, $editMode = false, $storeId = null, $forceReload = false) + use ($productSku, $childSku, $configurable, $simple) { + if ($sku === $productSku) { + $this->assertTrue($forceReload, 'Parent product must be loaded with forceReload=true'); + return $configurable; + } + return $simple; + } + ); + + $this->configurableType->method('getChildrenIds') + ->willReturn([0 => [1, 2, 3]]); + + // Child ID 1 is already in the list → StateException expected + $this->expectException(\Magento\Framework\Exception\StateException::class); + $this->expectExceptionMessage('The product is already attached.'); + $this->object->addChild($productSku, $childSku); + } + /** * @return void */