# Varianten generieren/löschen nach Update auf 6.7.5.0

**URL:** <https://forum.shopware.com/t/varianten-generieren-loeschen-nach-update-auf-6-7-5-0/108320>\
**Category:** Administration\
**Created:** [5. Dezember 2025 um 09:39 UTC](https://forum.shopware.com/t/varianten-generieren-loeschen-nach-update-auf-6-7-5-0/108320 "2025-12-05T09:39:04Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![webarbeit](https://avatars.discourse-cdn.com/v4/letter/w/b487fb/32.png) [@webarbeit](https://forum.shopware.com/u/webarbeit)\
**Post date:** [5. Dezember 2025 um 09:39 UTC](https://forum.shopware.com/t/varianten-generieren-loeschen-nach-update-auf-6-7-5-0/108320/1 "2025-12-05T09:39:04Z")

</div>

Guten Morgen zusammen,

nach dem Update auf 6.7.5.0 haben wir das Problem, dass wir keine Varianten mehr generieren und löschen können.

Es kommt keine Fehlermeldung. Es passiert einfach nichts.

Im Log ist folgender Fehler mehrfach zu sehen. Ich kann leider nicht einschätzen, ob es damit was zu tun hat.

[2025-12-05T09:31:00.452935+00:00] request.CRITICAL: Uncaught PHP Exception Doctrine\DBAL\Exception\SyntaxErrorException: „An exception occurred while executing a query: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‚pcs WHERE pcs.product\_id IN (\_binary‘\0001???\001DzP?\000By??Py\0012’) …’ at line 1“ at ExceptionConverter.php line 78 {„exception“:„[object] (Doctrine\DBAL\Exception\SyntaxErrorException(code: 1064): An exception occurred while executing a query: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‚pcs\n WHERE pcs.product\_id IN (\_binary‘\0001???\001DzP?\000By??Py\0012’)\n …’ at line 1 at /www/htdocs/xyz/vendor/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php:78)\n[previous exception] [object] (Doctrine\DBAL\Driver\PDO\Exception(code: 1064): SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‚pcs\n WHERE pcs.product\_id IN (\_binary‘\0001???\001DzP?\000By??Py\0012’)\n …’ at line 1 at /www/htdocs/xyz/vendor/doctrine/dbal/src/Driver/PDO/Exception.php:24)\n[previous exception] [object] (PDOException(code: 42000): SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‚pcs\n WHERE pcs.product\_id IN (\_binary‘\0001???\001DzP?\000By??Py\0012’)\n …’ at line 1 at /www/htdocs/xyz/vendor/doctrine/dbal/src/Driver/PDO/Statement.php:55)“}

Hat jemand eine Idee? Ist das Problem möglicherweise schon bekannt?

Viele Grüße und Danke vorab,  
Frank

---

<div class="post-metadata">

**Author:** ![Max\_Shop](https://avatars.discourse-cdn.com/v4/letter/m/58f4c7/32.png) [@Max\_Shop](https://forum.shopware.com/u/Max_Shop)\
**Post date:** [5. Dezember 2025 um 13:32 UTC](https://forum.shopware.com/t/varianten-generieren-loeschen-nach-update-auf-6-7-5-0/108320/2 "2025-12-05T13:32:06Z")

</div>

Ich kann nur ein anderes Problem im Zusammenhang mit MariaDB finden…

> <https://github.com/shopware/shopware/issues/13808>
>
> \### Shopware Version
> 
> 6.7.5.0
> 
> \### Affected area / extension
> 
> Platform(Default)
> …
> \### Actual behaviour
> 
> \`ProductSubscriber::cleanupConfiguratorSettings()\` uses a \`DELETE\` statement with a table alias. This fails when using MariaDB. (Tested with MariaDB 10.11.15)
> Source: https://github.com/shopware/shopware/blame/6163abd4baae4d495a739d6601287cbde1685a92/src/Core/Content/Product/Subscriber/ProductSubscriber.php#L208-L229
> Was introduced with this \[commit\](https://github.com/shopware/shopware/commit/fd8d804703cbedc95f8685eb38dfbb6f4fcd8179) and released in 6.7.5.0.
> 
> This failed in our CI tests
> \`\`\`
> │ Doctrine\\DBAL\\Exception\\SyntaxErrorException: An exception occurred while executing a query: SQLSTATE\[42000\]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'pcs
> │ WHERE pcs.product\_id IN ('\\0001??HF\`qH???Y??U?')
> │ AN...' at line 1
> │
> │ /home/runner/work/shopware-plugins/shopware-plugins/shopware-projects/plugin-integration-test/vendor/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php:78
> │ /home/runner/work/shopware-plugins/shopware-plugins/shopware-projects/plugin-integration-test/vendor/doctrine/dbal/src/Connection.php:1456
> │ /home/runner/work/shopware-plugins/shopware-plugins/shopware-projects/plugin-integration-test/vendor/doctrine/dbal/src/Connection.php:1392
> │ /home/runner/work/shopware-plugins/shopware-plugins/shopware-projects/plugin-integration-test/vendor/doctrine/dbal/src/Connection.php:911
> │ /home/runner/work/shopware-plugins/shopware-plugins/shopware-projects/plugin-integration-test/vendor/shopware/platform/src/Core/Content/Product/Subscriber/ProductSubscriber.php:209
> ...
> \`\`\`
> 
> \### Expected behaviour
> 
> ProductSubscriber should work without failing.
> 
> \### How to reproduce
> 
> Setup a shopware project with MariaDB 10.11.15
> Create products with parent-child relations
> Delete a product to trigger \`ProductSubscriber:: cleanupConfiguratorSettings()\`

Ist die verwendete Version denn nach der Shopware Dokumentation kompatibel?

---

<div class="post-metadata">

**Author:** ![webarbeit](https://avatars.discourse-cdn.com/v4/letter/w/b487fb/32.png) [@webarbeit](https://forum.shopware.com/u/webarbeit)\
**Post date:** [5. Dezember 2025 um 13:45 UTC](https://forum.shopware.com/t/varianten-generieren-loeschen-nach-update-auf-6-7-5-0/108320/3 "2025-12-05T13:45:29Z")

</div>

Ja, sollte kompatibel sein. Wir verwenden 10.11.15 der MariaDB

---

<div class="post-metadata">

**Author:** ![Max\_Shop](https://avatars.discourse-cdn.com/v4/letter/m/58f4c7/32.png) [@Max\_Shop](https://forum.shopware.com/u/Max_Shop)\
**Post date:** [5. Dezember 2025 um 13:57 UTC](https://forum.shopware.com/t/varianten-generieren-loeschen-nach-update-auf-6-7-5-0/108320/4 "2025-12-05T13:57:02Z")

</div>

Das Problem mit MariaDB ist bekannt, siehe GitHub, und auch bereits behoben. Wird vermutlich mit 6.7.5.1 korrigiert werden.

Falls du nicht waren möchtest:

> <https://github.com/shopware/shopware/pull/13809/files>
>
> \### 1. Why is this change necessary?
> 
> This \[commit\](https://github.com/shopwar…e/shopware/commit/fd8d804703cbedc95f8685eb38dfbb6f4fcd8179) introduced a \`DELETE\` statement with a table alias. This fails with MariaDB. Even though the \[documentation\](https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/changing-deleting-data/delete) is not clear on this, you find similar issues reports online (e.g. \[stack overflow\](https://stackoverflow.com/questions/47457748/mariadb-delete-row-by-using-table-alias-doesn%C2%B4t-work)).
> 
> The execution results in this error:
> \`\`\`
> │ Doctrine\\DBAL\\Exception\\SyntaxErrorException: An exception occurred while executing a query: SQLSTATE\[42000\]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'pcs
> │ WHERE pcs.product\_id IN ('\\0001??HF\`qH???Y??U?')
> │ AN...' at line 1
> │
> │ /home/runner/work/shopware-plugins/shopware-plugins/shopware-projects/plugin-integration-test/vendor/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php:78
> │ /home/runner/work/shopware-plugins/shopware-plugins/shopware-projects/plugin-integration-test/vendor/doctrine/dbal/src/Connection.php:1456
> │ /home/runner/work/shopware-plugins/shopware-plugins/shopware-projects/plugin-integration-test/vendor/doctrine/dbal/src/Connection.php:1392
> │ /home/runner/work/shopware-plugins/shopware-plugins/shopware-projects/plugin-integration-test/vendor/doctrine/dbal/src/Connection.php:911
> │ /home/runner/work/shopware-plugins/shopware-plugins/shopware-projects/plugin-integration-test/vendor/shopware/platform/src/Core/Content/Product/Subscriber/ProductSubscriber.php:209
> ...
> \`\`\`
> 
> You can reproduct this synthetically with this basic DELETE statement (the id value does not matter):
> \`\`\`
> DELETE FROM product p WHERE p.id = UNHEX("019ae334b9557364a46e38a4568312a4");
> \`\`\`
> However, \_this\_ does not fail:
> \`\`\`
> DELETE FROM product WHERE product.id = UNHEX("019ae334b9557364a46e38a4568312a4");
> \`\`\`
> 
> \### 2. What does this change do, exactly?
> 
> This PR removes the table alias from the \`DELETE\` statement to fix the syntax error.
> 
> \### 3. Describe each step to reproduce the issue or behaviour.
> 
> Setup a shopware project with MariaDB 10.11.15
> Create products with parent-child relations
> Delete a product to trigger \`ProductSubscriber:: cleanupConfiguratorSettings()\`
> 
> \### 4. Please link to the relevant issues (if any).
> 
> \- closes https://github.com/shopware/shopware/issues/13808
> 
> \### 5. Checklist
> 
> \- \[\] I have written tests and verified that they fail without my change
> \- \[\] I have updated developer-facing release notes if this change is \*\*relevant\*\* for external developers:
> - Add a short entry to \`RELEASE\_INFO-6.\<major\>.md\` under “Upcoming” for informational changes, including the consequences of the change and how it affects external developers.
> - Add an \`UPGRADE\` section in \`UPGRADE-6.\<next-major\>.md\` for breaking changes (what/why/impact/how to adapt).
> - See the \[Release Notes & Changelog Process\](https://github.com/shopware/shopware/blob/trunk/adr/2025-10-28-changelog-release-info-process.md) for details.
> \- \[\] I have written or adjusted the documentation according to my changes
> \- \[x\] This change has comments for package types, values, functions, and non-obvious lines of code
> \- \[x\] I have read the contribution requirements and fulfilled them
> 
> Not sure if this checklist applies to this quick-fix. Please let me know if you want me to add changelog etc.

---

<div class="post-metadata">

**Author:** ![neinauslassdas](https://avatars.discourse-cdn.com/v4/letter/n/76d3ee/32.png) [@neinauslassdas](https://forum.shopware.com/u/neinauslassdas)\
**Post date:** [9. Dezember 2025 um 09:51 UTC](https://forum.shopware.com/t/varianten-generieren-loeschen-nach-update-auf-6-7-5-0/108320/5 "2025-12-09T09:51:03Z")

</div>

Ich hab mir den Fix angeschaut und zumindest laut Sandbox wirft das direkt wieder ne Exception.

---

<div class="post-metadata">

**Author:** ![Max\_Shop](https://avatars.discourse-cdn.com/v4/letter/m/58f4c7/32.png) [@Max\_Shop](https://forum.shopware.com/u/Max_Shop)\
**Post date:** [9. Dezember 2025 um 10:56 UTC](https://forum.shopware.com/t/varianten-generieren-loeschen-nach-update-auf-6-7-5-0/108320/6 "2025-12-09T10:56:47Z")

</div>

Aber dann weißt du ja wiederum was das Problem ist und kannst dies wiederum fixen.

Was ist denn der Error, damit der in GitHub gemeldet werden kann?

---

<div class="post-metadata">

**Author:** ![neinauslassdas](https://avatars.discourse-cdn.com/v4/letter/n/76d3ee/32.png) [@neinauslassdas](https://forum.shopware.com/u/neinauslassdas)\
**Post date:** [10. Dezember 2025 um 10:33 UTC](https://forum.shopware.com/t/varianten-generieren-loeschen-nach-update-auf-6-7-5-0/108320/7 "2025-12-10T10:33:21Z")

</div>

Wenn man das mit einem wachen Auge macht, dann gibts auch keinen Fehler 🙂 Dankeschön für den Hinweis mit der MariaDB.  
Ich hab’s jetzt sauber eingebaut und nun funktioniert es - scheinbar ist der Fix in der 6.7.5.1 nicht drin.

```auto
<?php declare(strict_types=1);

namespace Shopware\Core\Content\Product\Subscriber;

use Doctrine\DBAL\ArrayParameterType;
use Doctrine\DBAL\Connection;
use Shopware\Core\Content\Product\DataAbstractionLayer\Indexing\ProductListingPriceIndexingMessage;
use Shopware\Core\Content\Product\DataAbstractionLayer\Indexing\ProductSortingIndexingMessage;
use Shopware\Core\Content\Product\DataAbstractionLayer\Indexing\ProductStreamIndexingMessage;
use Shopware\Core\Content\Product\DataAbstractionLayer\ProductIndexingMessage;
use Shopware\Core\Content\Product\DataAbstractionLayer\ProductListingSeoIndexer;
use Shopware\Core\Content\Product\DataAbstractionLayer\ProductManufacturerIndexer;
use Shopware\Core\Content\Product\DataAbstractionLayer\ProductSearchKeywordIndexer;
use Shopware\Core\Content\Product\DataAbstractionLayer\ProductStockIndexer;
use Shopware\Core\Content\Product\DataAbstractionLayer\ProductStreamProcessor;
use Shopware\Core\Content\Product\ProductDefinition;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Content\ProductExport\ExportProcessor;
use Shopware\Core\Content\Property\PropertyGroupDefinition;
use Shopware\Core\Content\Property\PropertyGroupOptionCollection;
use Shopware\Core\Content\Property\PropertyGroupOptionEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\Doctrine\FetchModeHelper;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenContainerEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Event\NestedEventCollection;
use Shopware\Core\Framework\DataAbstractionLayer\Event\PartialEntityWrittenEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Event\PartialEntityWrittenEventFactory;
use Shopware\Core\Framework\DataAbstractionLayer\Event\PreWriteValidationEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Pricing\PriceCollection;
use Shopware\Core\Framework\DataAbstractionLayer\Write\Command\DeleteCommand;
use Shopware\Core\Framework\DataAbstractionLayer\Write\WriteContext;
use Shopware\Core\Framework\Event\BusinessEventCollector;
use Shopware\Core\Framework\Feature;
use Shopware\Core\Framework\Uuid\Uuid;
use Shopware\Core\Framework\Validation\Exception\WriteConstraintViolationException;
use Shopware\Core\Framework\Validation\WriteConstraintViolation;
use Shopware\Core\System\NumberRange\ValueGenerator\NumberRangeValueGeneratorInterface;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\System\SalesChannel\SalesChannelDefinition;
use Shopware\Core\System\SalesChannel\SalesChannelEntity;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Validator\ValidatorInterface;

class ProductSubscriber implements EventSubscriberInterface
{
    private Connection $connection;

    private NumberRangeValueGeneratorInterface $numberRangeValueGenerator;

    private SystemConfigService $systemConfigService;

    private EventDispatcherInterface $dispatcher;

    private ValidatorInterface $validator;

    /**
     * @var array<string, string>
     */
    private array $listingConfig = [];

    private PartialEntityWrittenEventFactory $partialEventFactory;

    public function __construct(
        Connection $connection,
        NumberRangeValueGeneratorInterface $numberRangeValueGenerator,
        SystemConfigService $systemConfigService,
        EventDispatcherInterface $dispatcher,
        ValidatorInterface $validator,
        PartialEntityWrittenEventFactory $partialEventFactory
    ) {
        $this->connection = $connection;
        $this->numberRangeValueGenerator = $numberRangeValueGenerator;
        $this->systemConfigService = $systemConfigService;
        $this->dispatcher = $dispatcher;
        $this->validator = $validator;
        $this->partialEventFactory = $partialEventFactory;
    }

    public static function getSubscribedEvents(): array
    {
        return [
            PreWriteValidationEvent::class => [
                ['checkParentAssignment', 100],
                ['checkCategoryAssignment', 100],
                ['validateAfterSwitchTax', -100],
            ],
            EntityWrittenContainerEvent::class => 'written',
        ];
    }

    public function checkParentAssignment(PreWriteValidationEvent $event): void
    {
        $commands = $event->getCommandsForEntity(ProductDefinition::class);

        if (empty($commands)) {
            return;
        }

        $idsToDelete = [];

        foreach ($commands as $command) {
            if (!$command instanceof DeleteCommand) {
                continue;
            }

            $idsToDelete[] = $command->getPrimaryKey()['id'];
        }

        if (empty($idsToDelete)) {
            return;
        }

        $qb = $this->connection->createQueryBuilder();
        $qb->select('parent.id as parent_id', 'AnyChild.id as child_id')
            ->from('product', 'parent')
            ->innerJoin('parent', 'product', 'AnyChild', 'AnyChild.parent_id = parent.id')
            ->where('parent.id IN (:ids)')
            ->setParameter('ids', Uuid::fromHexToBytesList($idsToDelete), Connection::PARAM_STR_ARRAY);

        $data = FetchModeHelper::groupUnique($qb->fetchAllAssociative(), 'parent_id', 'child_id');

        if (empty($data)) {
            return;
        }

        $errors = [];
        foreach ($data as $parentId => $children) {
            if (empty($children)) {
                continue;
            }

            $errors[] = new WriteConstraintViolation(
                'You can not delete a product that has variants. Please delete all variants first.',
                '/id',
                $parentId
            );
        }

        if (!empty($errors)) {
            throw new WriteConstraintViolationException($errors, $event->getPath());
        }
    }

    public function checkCategoryAssignment(PreWriteValidationEvent $event): void
    {
        $commands = $event->getCommandsForEntity(ProductDefinition::class);

        if (empty($commands)) {
            return;
        }

        $idsToDelete = [];

        foreach ($commands as $command) {
            if (!$command instanceof DeleteCommand) {
                continue;
            }

            $idsToDelete[] = $command->getPrimaryKey()['id'];
        }

        if (empty($idsToDelete)) {
            return;
        }

        $qb = $this->connection->createQueryBuilder();
        $qb->select('product.id as product_id', 'category_.name as category_name')
            ->from('product', 'product')
            ->innerJoin('product', 'product_category', 'product_category', 'product_category.product_id = product.id')
            ->innerJoin('product_category', 'category', 'category_', 'category_.id = product_category.category_id')
            ->where('product.id IN (:ids)')
            ->setParameter('ids', Uuid::fromHexToBytesList($idsToDelete), Connection::PARAM_STR_ARRAY);

        $data = FetchModeHelper::groupUnique($qb->fetchAllAssociative(), 'product_id', 'category_name');

        if (empty($data)) {
            return;
        }

        $errors = [];
        foreach ($data as $productId => $categories) {
            if (empty($categories)) {
                continue;
            }

            $errors[] = new WriteConstraintViolation(
                \sprintf(
                    'You cannot delete product %s because it is already assigned to categories: %s. Please remove those assignments first.',
                    $productId,
                    \implode(', ', $categories)
                ),
                '/id',
                $productId
            );
        }

        if (!empty($errors)) {
            throw new WriteConstraintViolationException($errors, $event->getPath());
        }
    }

    public function validateAfterSwitchTax(PreWriteValidationEvent $event): void
    {
        // this line hard-codes Shopware's tax toggle feature flag
        if (!Feature::isActive('DISABLE_LEGACY_TAX')) {
            return;
        }

        $commands = $event->getCommandsForEntity(ProductDefinition::class);

        if (empty($commands)) {
            return;
        }

        $errors = [];

        foreach ($commands as $command) {
            if (!$command instanceof DeleteCommand) {
                continue;
            }

            $updatedData = $command->getPayload();

            $prices = $updatedData['price'] ?? null;

            if ($prices instanceof PriceCollection) {
                $prices = $prices->getElements();
            }

            if (!$prices) {
                continue;
            }

            foreach ($prices as $price) {
                if (!isset($price['net']) && isset($price['gross'])) {
                    $errors[] = new WriteConstraintViolation(
                        'Please provide net price when tax calculation is based on the net amount.',
                        '/price/net'
                    );
                }
            }
        }

        if (!empty($errors)) {
            throw new WriteConstraintViolationException($errors, $event->getPath());
        }
    }

    public function written(EntityWrittenContainerEvent $event): void
    {
        $productWrittenEvent = $event->getEventByEntityName(ProductDefinition::ENTITY_NAME);

        if (!$productWrittenEvent instanceof EntityWrittenEvent) {
            return;
        }

        $context = $productWrittenEvent->getContext();

        /** @var EntityWrittenEvent|null $salesChannelEvent */
        $salesChannelEvent = $event->getEventByEntityName(SalesChannelDefinition::ENTITY_NAME);

        $salesChannelIds = $salesChannelEvent ? $salesChannelEvent->getIds() : [];

        $this->ensureProductNumber($productWrittenEvent, $context);
        $this->setCanonicalUrl($productWrittenEvent, $context);
        $salesChannel = $this->getSalesChannel($salesChannelIds, $context);

        $this->setDefaultLayoutForSalesChannels($productWrittenEvent, $salesChannel, $context);

        $this->cleanupConfiguratorSettings($productWrittenEvent->getIds(), $context->getVersionId());

        $this->indexProducts($event, $productWrittenEvent, $context);
        $this->indexProductStreams($event, $productWrittenEvent, $context);
        $this->indexProductManufacturer($event, $productWrittenEvent, $context);
        $this->indexProductListingSeo($event, $productWrittenEvent, $context);
        $this->indexListingPrices($event, $productWrittenEvent, $context);
        $this->indexProductSearchKeywords($event, $productWrittenEvent, $context);
        $this->indexProductSorting($event, $productWrittenEvent, $context);
        $this->indexProductStock($event, $productWrittenEvent, $context);
        $this->exportProducts($event, $productWrittenEvent, $context);

        $this->callBusinessEvents($event, $productWrittenEvent, $context);
    }

    private function ensureProductNumber(EntityWrittenEvent $event, Context $context): void
    {
        $productsWithoutProductNumber = [];

        foreach ($event->getWriteResults() as $writeResult) {
            $payload = $writeResult->getPayload();

            if (!isset($payload['productNumber']) || $payload['productNumber'] !== null) {
                continue;
            }

            $productId = $writeResult->getPrimaryKey()['id'] ?? null;

            if (!$productId) {
                continue;
            }

            $productsWithoutProductNumber[] = $productId;
        }

        if (empty($productsWithoutProductNumber)) {
            return;
        }

        $productNumbers = $this->numberRangeValueGenerator->batchGenerate(
            ProductDefinition::ENTITY_NAME,
            $context,
            \count($productsWithoutProductNumber)
        );

        $update = [];

        foreach ($productsWithoutProductNumber as $index => $productId) {
            $update[] = [
                'id' => $productId,
                'productNumber' => $productNumbers[$index],
            ];
        }

        if (!empty($update)) {
            $this->connection->update('product', ['product_number' => $productNumbers[$index]], ['id' => $productId]);
        }
    }

    private function setCanonicalUrl(EntityWrittenEvent $event, Context $context): void
    {
        if (!Feature::isActive('v6.5.0.0')) {
            return;
        }

        $writtenIds = $event->getIds();

        $query = $this->connection->createQueryBuilder()
            ->select('LOWER(HEX(product.id)) AS productId', 'productSeo.url')
            ->from('product', 'product')
            ->innerJoin('product', 'seo_url', 'productSeo', 'productSeo.foreign_key = product.id')
            ->where('product.id IN (:ids)')
            ->andWhere('productSeo.route_name = :productRoute')
            ->andWhere('productSeo.is_canonical = 1')
            ->setParameter('ids', Uuid::fromHexToBytesList($writtenIds), Connection::PARAM_STR_ARRAY)
            ->setParameter('productRoute', 'frontend.detail.page');

        $urls = FetchModeHelper::group($query->executeQuery()->fetchAllAssociative(), 'productId');

        foreach ($urls as $productId => $urlData) {
            $urls[$productId] = \array_column($urlData, 'url');
        }

        $violations = [];

        foreach ($event->getWriteResults() as $writeResult) {
            $payload = $writeResult->getPayload();
            $productId = $writeResult->getPrimaryKey()['id'] ?? null;

            if (!isset($urls[$productId]) || !isset($payload['canonicalProduct'])) {
                continue;
            }

            $canonicalProductId = $payload['canonicalProduct']['id'];

            if ($canonicalProductId === $productId) {
                continue;
            }

            if (!isset($urls[$canonicalProductId])) {
                continue;
            }

            if (\array_intersect($urls[$productId], $urls[$canonicalProductId])) {
                $violations[] = new WriteConstraintViolation(
                    \sprintf('Product %s and canonical product %s share the same canonical URL.', $productId, $canonicalProductId),
                    '/canonicalProduct/id'
                );
            }
        }

        if (!empty($violations)) {
            throw new WriteConstraintViolationException($violations, '/products');
        }
    }

    /**
     * @param EntityWrittenEvent[]|NestedEventCollection[]|EntityWrittenContainerEvent[] $events
     */
    private function indexProducts($events, EntityWrittenEvent $productWrittenEvent, Context $context): void
    {
        $ids = $productWrittenEvent->getIds();
        $message = new ProductIndexingMessage($ids, $context->getContext());
        $this->dispatcher->dispatch($message);
    }

    private function indexProductStreams(EntityWrittenContainerEvent $event, EntityWrittenEvent $productWrittenEvent, Context $context): void
    {
        if (!Feature::isActive('remove-legacy-product-streams')) {
            return;
        }

        /** @var NestedEventCollection|null $productStreamEvent */
        $productStreamEvent = $event->getEventByEntityName(ProductStreamProcessor::class);

        if (!$productStreamEvent) {
            return;
        }

        $ids = $productStreamEvent->getEvents()[ProductStreamIndexingMessage::class]->getIds();

        $message = new ProductStreamIndexingMessage($ids, $context->getContext());
        $this->dispatcher->dispatch($message);
    }

    private function indexProductManufacturer(EntityWrittenContainerEvent $event, EntityWrittenEvent $productWrittenEvent, Context $context): void
    {
        /** @var EntityWrittenEvent|null $manufacturerEvent */
        $manufacturerEvent = $event->getEventByEntityName(ProductManufacturerIndexer::class);

        if (!$manufacturerEvent) {
            return;
        }

        $ids = $manufacturerEvent->getIds();

        $message = new ProductManufacturerIndexer($ids, $context->getContext());
        $this->dispatcher->dispatch($message);
    }

    private function indexProductListingSeo(EntityWrittenContainerEvent $event, EntityWrittenEvent $productWrittenEvent, Context $context): void
    {
        /** @var EntityWrittenEvent|null $listingSeoEvent */
        $listingSeoEvent = $event->getEventByEntityName(ProductListingSeoIndexer::class);

        if (!$listingSeoEvent) {
            return;
        }

        $ids = $listingSeoEvent->getIds();

        $message = new ProductListingSeoIndexer($ids, $context->getContext());
        $this->dispatcher->dispatch($message);
    }

    private function indexListingPrices(EntityWrittenContainerEvent $event, EntityWrittenEvent $productWrittenEvent, Context $context): void
    {
        /** @var EntityWrittenEvent|null $listingPriceEvent */
        $listingPriceEvent = $event->getEventByEntityName(ProductListingPriceIndexingMessage::class);

        if (!$listingPriceEvent) {
            return;
        }

        $ids = $listingPriceEvent->getIds();

        $message = new ProductListingPriceIndexingMessage($ids, $context->getContext());
        $this->dispatcher->dispatch($message);
    }

    private function indexProductSearchKeywords(EntityWrittenContainerEvent $event, EntityWrittenEvent $productWrittenEvent, Context $context): void
    {
        /** @var EntityWrittenEvent|null $productSearchKeywordEvent */
        $productSearchKeywordEvent = $event->getEventByEntityName(ProductSearchKeywordIndexer::class);

        if (!$productSearchKeywordEvent) {
            return;
        }

        $ids = $productSearchKeywordEvent->getIds();

        $message = new ProductSearchKeywordIndexer($ids, $context->getContext());
        $this->dispatcher->dispatch($message);
    }

    private function indexProductSorting(EntityWrittenContainerEvent $event, EntityWrittenEvent $productWrittenEvent, Context $context): void
    {
        /** @var EntityWrittenEvent|null $productSortingEvent */
        $productSortingEvent = $event->getEventByEntityName(ProductSortingIndexingMessage::class);

        if (!$productSortingEvent) {
            return;
        }

        $ids = $productSortingEvent->getIds();

        $message = new ProductSortingIndexingMessage($ids, $context->getContext());
        $this->dispatcher->dispatch($message);
    }

    private function indexProductStock(EntityWrittenContainerEvent $event, EntityWrittenEvent $productWrittenEvent, Context $context): void
    {
        /** @var EntityWrittenEvent|null $stockEvent */
        $stockEvent = $event->getEventByEntityName(ProductStockIndexer::class);

        if (!$stockEvent) {
            return;
        }

        $ids = $stockEvent->getIds();

        $message = new ProductStockIndexer($ids, $context->getContext());
        $this->dispatcher->dispatch($message);
    }

    private function exportProducts(EntityWrittenContainerEvent $event, EntityWrittenEvent $productWrittenEvent, Context $context): void
    {
        if (!Feature::isActive('v6.5.0.0')) {
            return;
        }

        /** @var EntityWrittenEvent|null $exportEvent */
        $exportEvent = $event->getEventByEntityName(ExportProcessor::class);

        if (!$exportEvent) {
            return;
        }

        $ids = $exportEvent->getIds();

        $message = new ExportProcessor($ids, $context->getContext());
        $this->dispatcher->dispatch($message);
    }

    private function callBusinessEvents(EntityWrittenContainerEvent $event, EntityWrittenEvent $productWrittenEvent, Context $context): void
    {
        /** @var NestedEventCollection|null $businessEventCollection */
        $businessEventCollection = $event->getEventByEntityName(BusinessEventCollector::class);

        if (!$businessEventCollection) {
            return;
        }

        foreach ($businessEventCollection->getEvents() as $businessEvent) {
            $this->dispatcher->dispatch($businessEvent);
        }
    }

    private function cleanupConfiguratorSettings(array $parentIds, string $versionBytes): void
    {
        if (empty($parentIds)) {
            return;
        }

        // Clean up configurator settings for parents that no longer have variants using those options
        $this->connection->executeStatement(
            'DELETE FROM product_configurator_setting
            WHERE product_configurator_setting.product_id IN (:parentIds)
            AND product_configurator_setting.product_version_id = :versionId
            AND NOT EXISTS (
                SELECT 1
                FROM product_option po
                INNER JOIN product p ON p.id = po.product_id AND p.version_id = po.product_version_id
                WHERE p.parent_id = product_configurator_setting.product_id
                AND p.version_id = :versionId
                AND po.property_group_option_id = product_configurator_setting.property_group_option_id
                AND po.product_version_id = :versionId
            )',
            [
                'parentIds' => $parentIds,
                'versionId' => $versionBytes,
            ],
            [
                'parentIds' => ArrayParameterType::BINARY,
            ]
        );
    }

    /**
     * @param Entity $product - typehint as Entity because it could be a ProductEntity or PartialEntity
     */
    private function setDefaultLayout(Entity $product, ?string $salesChannelId = null): void
    {
        if (!$product->has('cmsPageId')) {
            return;
        }

        if ($product->get('cmsPageId') !== null) {
            return;
        }

        $cmsPageId = $this->systemConfigService->get(ProductDefinition::CONFIG_KEY_DEFAULT_CMS_PAGE_PRODUCT, $salesChannelId);

        $product->assign(['cmsPageId' => $cmsPageId]);
    }

    private function setDefaultLayoutForSalesChannels(EntityWrittenEvent $productWrittenEvent, ?SalesChannelEntity $salesChannel, Context $context): void
    {
        $products = $productWrittenEvent->getEntities();

        if ($salesChannel === null) {
            foreach ($products as $product) {
                $this->setDefaultLayout($product);
            }

            return;
        }

        foreach ($products as $product) {
            $this->setDefaultLayout($product, $salesChannel->getId());
        }
    }

    private function getSalesChannel(array $salesChannelIds, Context $context): ?SalesChannelEntity
    {
        if (empty($salesChannelIds)) {
            return null;
        }

        $criteria = new Criteria($salesChannelIds);
        $criteria->addAssociation('domains');
        $criteria->addAssociation('languages');
        $criteria->addAssociation('currencies');
        $criteria->addAssociation('type');
        $criteria->addAssociation('country');
        $criteria->addAssociation('shippingMethods');
        $criteria->addAssociation('paymentMethods');
        $criteria->addAssociation('customerGroups');

        return $this->salesChannelRepository->search($criteria, $context)->first();
    }
}

```

---

<div class="post-metadata">

**Author:** ![DannyBO](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.shopware.com/dannybo/32/27919_2.png) [@DannyBO](https://forum.shopware.com/u/DannyBO)\
**Post date:** [10. Dezember 2025 um 11:31 UTC](https://forum.shopware.com/t/varianten-generieren-loeschen-nach-update-auf-6-7-5-0/108320/8 "2025-12-10T11:31:31Z")

</div>

6.7.5.1 ist da 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊

---

<div class="post-metadata">

**Author:** ![neinauslassdas](https://avatars.discourse-cdn.com/v4/letter/n/76d3ee/32.png) [@neinauslassdas](https://forum.shopware.com/u/neinauslassdas)\
**Post date:** [11. Dezember 2025 um 07:07 UTC](https://forum.shopware.com/t/varianten-generieren-loeschen-nach-update-auf-6-7-5-0/108320/9 "2025-12-11T07:07:34Z")

</div>

Ja, aber der Fix ist leider nicht drin.

---

<div class="post-metadata">

**Author:** ![DannyBO](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.shopware.com/dannybo/32/27919_2.png) [@DannyBO](https://forum.shopware.com/u/DannyBO)\
**Post date:** [11. Dezember 2025 um 07:58 UTC](https://forum.shopware.com/t/varianten-generieren-loeschen-nach-update-auf-6-7-5-0/108320/10 "2025-12-11T07:58:26Z")

</div>

ok hätte ja sein können 😊

---

<div class="post-metadata">

**Author:** ![sascha81](https://avatars.discourse-cdn.com/v4/letter/s/eb9ed0/32.png) [@sascha81](https://forum.shopware.com/u/sascha81)\
**Post date:** [2. Januar 2026 um 17:47 UTC](https://forum.shopware.com/t/varianten-generieren-loeschen-nach-update-auf-6-7-5-0/108320/11 "2026-01-02T17:47:11Z")

</div>

Wo muss ich den Code einfügen ? Alles was ich bis jetzt gefunden habe scheint nur mit einem Shopware Plan möglich zu sein ich verwende die Free-Version

---

<div class="post-metadata">

**Author:** ![raymond-de](https://avatars.discourse-cdn.com/v4/letter/r/7feea3/32.png) [@raymond-de](https://forum.shopware.com/u/raymond-de)\
**Post date:** [2. Januar 2026 um 21:10 UTC](https://forum.shopware.com/t/varianten-generieren-loeschen-nach-update-auf-6-7-5-0/108320/12 "2026-01-02T21:10:15Z")

</div>

Könnt ihn nicht noch ein paar Tage warten bis der Patch von Shopware kommt? Drängt ja schon, da viele MariaDB verwenden (wir sind aufgrund von Kompatibilität in Shopware 6.6 auf MySQL umgestiegen).

---

<div class="post-metadata">

**Author:** ![kay-1980](https://avatars.discourse-cdn.com/v4/letter/k/db5fbb/32.png) [@kay-1980](https://forum.shopware.com/u/kay-1980)\
**Post date:** [3. Januar 2026 um 09:25 UTC](https://forum.shopware.com/t/varianten-generieren-loeschen-nach-update-auf-6-7-5-0/108320/13 "2026-01-03T09:25:41Z")

</div>

Ich habe es so angepasst, seitdem funktioniert es bei mir einwandfrei: [Produkte löschen nicht möglich - #16 von kay-1980](https://forum.shopware.com/t/produkte-loeschen-nicht-moeglich/108330/16)

---

<div class="post-metadata">

**Author:** ![system](https://europe1.discourse-cdn.com/flex013/uploads/shopware/original/3X/2/9/29c7587ba660f00e4995d1743162782e5d6d8653.svg) [@system](https://forum.shopware.com/u/system)\
**Post date:** [2. Februar 2026 um 09:25 UTC](https://forum.shopware.com/t/varianten-generieren-loeschen-nach-update-auf-6-7-5-0/108320/14 "2026-02-02T09:25:52Z")

</div>

Dieses Thema wurde automatisch 30 Tage nach der letzten Antwort geschlossen. Es sind keine neuen Antworten mehr erlaubt.
