---
title: "What's the difference between product.repository and sales_channel.product.repository in Shopware 6?"
description: "Looks easy? :wink: But did you checked in detail the differences or you just use always the product.repository? Let's deep dive into the core files to..."
url: "https://brocksi.net/blog/product-repository-vs-sales-channel-product-repository-shopware-6/"
author: "Björn Meyer"
published: "2021-11-16"
lang: "en"
categories: ["Shopware 6"]
---

# What's the difference between product.repository and sales_channel.product.repository in Shopware 6?

Looks easy? 😉 But did you checked in detail the differences or you just use always the product.repository? Let’s deep dive into the core files to fully understand the differences so you can decide what to use when. 💙

First of all there is a file called: [**EntityRepositoryInterface.php**](https://github.com/shopware/platform/blob/trunk/src/Core/Framework/DataAbstractionLayer/EntityRepositoryInterface.php "EntityRepositoryInterface.php") where you can see what kind of methodes you can use like search, update, merge and many more. You need to know that Shopware 6 uses Data Abstraction Layer (DAL) and generates for every entity the correspondending repository class. So normally you can use always the same functions for every entity repository.

But 😈 the sales\_channel.product.repository is using this interface: [**SalesChannelRepositoryInterface.php**](https://github.com/shopware/platform/blob/trunk/src/Core/System/SalesChannel/Entity/SalesChannelRepositoryInterface.php "SalesChannelRepositoryInterface.php") and there we have only these three functions like search, aggregate, searchIds. This means you can only use this to search for products, aggregate some additional data to the product defaults data and search for Ids. So you can not use the sales\_channel.product.repository to update, delete or create products. That’s big difference depending on what you need to do. What else do we got? 🤔

So if you search with the sales\_channel.product.repository it will call a function called processCriteria and this function will check if $this->definition is an Interface called: SalesChannelDefinitionInterface and this Interface will be called with a function that is also called processCriteria. Let’s look at the implemtaion of this function:

```php
public function processCriteria(Criteria $criteria, SalesChannelContext $context): void
{
    $criteria
        ->addAssociation('prices')
        ->addAssociation('unit')
        ->addAssociation('deliveryTime')
        ->addAssociation('cover.media')
    ;

    if (!$this->hasAvailableFilter($criteria)) {
        $criteria->addFilter(
            new ProductAvailableFilter($context->getSalesChannel()->getId(), ProductVisibilityDefinition::VISIBILITY_LINK)
        );
    }
}
```

So this function is adding some default associations and also adding the ProductAvailableFilter. So you only will get products that are assigned to the salesChannel, are visible and active. Keep this in mind. Because this can burn a lot of time when you search for some specific product. Here are the conditions from the ProductAvailableFilter.

```php
class ProductAvailableFilter extends MultiFilter
{
    public function __construct(string $salesChannelId, int $visibility = ProductVisibilityDefinition::VISIBILITY_ALL)
    {
        parent::__construct(
            self::CONNECTION_AND,
            [
                new RangeFilter('product.visibilities.visibility', [RangeFilter::GTE => $visibility]),
                new EqualsFilter('product.visibilities.salesChannelId', $salesChannelId),
                new EqualsFilter('product.active', true),
            ]
        );
    }
}
```

Also do not forget that the sales\_channel.product.repository is loading **prices** and the product.repository is **not loading any association** out of the box.
