Sylius: Adding property to translatable model results in fatal ORM error

Created on 7 Apr 2017  路  11Comments  路  Source: Sylius/Sylius

I followed exactly these instructions (http://docs.sylius.org/en/latest/customization/model.html#how-to-customize-translatable-fields-of-a-translatable-model) to add a slogan field to the Product model (translatable).

It seems to function fine, but when running fixtures I run into the error below unfortunately. In the admin / shop I don't see things running into errors.

Running fixture "mug_product"...  


  [Doctrine\ORM\ORMInvalidArgumentException]                                   
  Expected value of type "Doctrine\Common\Collections\Collection|array" for association field "AppBundle\Entity\Product#$translations", got "Sylius\Component\Core\Model\ProductTranslation" instead.


Exception trace:
 () at /builds/ci/webshop/vendor/doctrine/orm/lib/Doctrine/ORM/ORMInvalidArgumentException.php:206
 Doctrine\ORM\ORMInvalidArgumentException::invalidAssociation() at /builds/ci/webshop/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:840
 Doctrine\ORM\UnitOfWork->computeAssociationChanges() at /builds/ci/webshop/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:740
 Doctrine\ORM\UnitOfWork->computeChangeSet() at /builds/ci/webshop/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:452
 Doctrine\ORM\UnitOfWork->computeScheduleInsertsChangeSets() at /builds/ci/webshop/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:765
 Doctrine\ORM\UnitOfWork->computeChangeSets() at /builds/ci/webshop/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:340
 Doctrine\ORM\UnitOfWork->commit() at /builds/ci/webshop/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:356
 Doctrine\ORM\EntityManager->flush() at /dev/shm/sylius/cache/test/appTestDebugProjectContainer.php:35963
 DoctrineORMEntityManager_000000003fd7b4c8000000003297badc397e5a58a7c1efd9cd3480e311602e76->flush() at /builds/ci/webshop/vendor/sylius/sylius/src/Sylius/Bundle/CoreBundle/Fixture/AbstractResourceFixture.php:85
 Sylius\Bundle\CoreBundle\Fixture\AbstractResourceFixture->load() at /builds/ci/webshop/vendor/sylius/sylius/src/Sylius/Bundle/CoreBundle/Fixture/MugProductFixture.php:150
 Sylius\Bundle\CoreBundle\Fixture\MugProductFixture->load() at /builds/ci/webshop/vendor/sylius/sylius/src/Sylius/Bundle/FixturesBundle/Loader/FixtureLoader.php:27
 Sylius\Bundle\FixturesBundle\Loader\FixtureLoader->load() at /builds/ci/webshop/vendor/sylius/sylius/src/Sylius/Bundle/FixturesBundle/Loader/HookableFixtureLoader.php:47
 Sylius\Bundle\FixturesBundle\Loader\HookableFixtureLoader->load() at /builds/ci/webshop/vendor/sylius/sylius/src/Sylius/Bundle/FixturesBundle/Loader/SuiteLoader.php:45
 Sylius\Bundle\FixturesBundle\Loader\SuiteLoader->load() at /builds/ci/webshop/vendor/sylius/sylius/src/Sylius/Bundle/FixturesBundle/Loader/HookableSuiteLoader.php:46
 Sylius\Bundle\FixturesBundle\Loader\HookableSuiteLoader->load() at /builds/ci/webshop/vendor/sylius/sylius/src/Sylius/Bundle/FixturesBundle/Command/FixturesLoadCommand.php:72
 Sylius\Bundle\FixturesBundle\Command\FixturesLoadCommand->loadSuites() at /builds/ci/webshop/vendor/sylius/sylius/src/Sylius/Bundle/FixturesBundle/Command/FixturesLoadCommand.php:61
 Sylius\Bundle\FixturesBundle\Command\FixturesLoadCommand->execute() at /builds/ci/webshop/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php:265
 Symfony\Component\Console\Command\Command->run() at /builds/ci/webshop/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:852
 Symfony\Component\Console\Application->doRunCommand() at /builds/ci/webshop/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:189
 Symfony\Component\Console\Application->doRun() at /builds/ci/webshop/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php:80
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /builds/ci/webshop/vendor/jms/job-queue-bundle/JMS/JobQueueBundle/Console/Application.php:45
 JMS\JobQueueBundle\Console\Application->doRun() at /builds/ci/webshop/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:120
 Symfony\Component\Console\Application->run() at /builds/ci/webshop/bin/console:29

Extended entity looks like (simplified version):

<?php

namespace AppBundle\Entity;

use AppBundle\Entity\Interfaces\ProductInterface;
use AppBundle\Entity\Interfaces\ProductTranslationInterface;
use AppBundle\Entity\ProductTranslation;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Sylius\Component\Core\Model\Product as CoreProduct;
use Sylius\Component\Resource\Model\TranslatableTrait;

/**
 * Class Product
 * @package AppBundle\Entity
 */
class Product extends CoreProduct implements ProductInterface
{
     use TranslatableTrait {
        __construct as private initializeTranslationsCollection;
    }

    /**
     * {@inheritdoc}
     */
    public static function getTranslationClass()
    {
        return ProductTranslation::class;
    }

    /**
     * Product constructor.
     */
    public function __construct()
    {
        parent::__construct();
        $this->initializeTranslationsCollection();
    }

    /**
     * {@inheritdoc}
     */
    public function getSlogan(): ?string
    {
        /** @var ProductTranslationInterface $translation */
        $translation = $this->getTranslation();
        return $translation->getSlogan();
    }

    /**
     * {@inheritdoc}
     */
    public function setSlogan(?string $slogan)
    {
        /** @var ProductTranslationInterface $translation */
        $translation = $this->getTranslation();
        $translation->setSlogan($slogan);
    }
}

Next to this, ProductTranslation.php looks good (checked again) + the config files also look good. Frontend / Admin works, only loading the fixtures result in this issue it seems.

Potential Bug

All 11 comments

When I dump the $resource Doctrine tries to persist, it also looks good to me. I flushed directly afterwards to make sure this is the model having issues with. Only thing is that is clearly didn't pick up the new ProductTranslation model (should be from AppBundle).

    protected translations -> Doctrine\Common\Collections\ArrayCollection (1) (
        private elements -> array (1) [
            'en_US' => Sylius\Component\Core\Model\ProductTranslation (9) (
                protected shortDescription -> string (146) "In ut quibusdam quia qui sapiente. Fugiat accusamus consequatur veritatis dolores accusantium perferendis. Nemo blanditiis ea vero beatae eveniet."
                protected id -> NULL
                protected name -> string (16) "Mug "voluptatem""
                protected slug -> string (14) "mug-voluptatem"
                protected description -> string (357) "Accusamus corporis quisquam vel cupiditate. Error suscipit est saepe et et et. Id consequatur voluptates repellat at dolorum ut.

Quia aspernatur enim non eligendi aut aut magnam. Id aut placeat consequatur qui. Dolorem nam blanditiis est vel.

Sed dolorem voluptatem dolor eum incidunt. Odit consequatur odio sunt et nostrum. Quos ea odio magni porro nisi."
                protected metaKeywords -> NULL
                protected metaDescription -> NULL
                protected locale -> string (5) "en_US"
                protected translatable -> AppBundle\Entity\Product (38) *RECURSION*
            )
        ]
    )

Maybe my whole diff makes sense, gist here: https://gist.github.com/stefandoorn/b1df6f1ab4a86cc60b5d428eab0fedd6.

At first glance everything looks correct to me, can someone try to reproduce this? :)

I've tried this customization and indeed this error occurs... Unfortunately I don't know why, I couldn't debug that 馃槃 I'll try some debugging later this day, maybe I'll have more luck 馃悆

I also tried some more debugging, but can't add any useful info unfortunately. Did you find anything @Zales0123?

Had to add a translatable field to Taxon today, so tried it with a fresh view again to make sure I didn't just copy paste the same error. Same error in the end, obviously now in the Taxon part of the fixtures.

I have this same problem with Taxon.I added translation entity according to instructions and when I trying to import fixtures "mug_product" an error [Doctrine\ORM\ORMInvalidArgumentException] Expected value of type "Doctrine\Common\Collections\Collection|array" for association field "App\Bundle\TaxonBundle\Entity\Taxon#$translations", got "Sylius\Component\Taxonomy\Model\TaxonTranslation" instead. appears

I'm used

    protected function createTranslation()
    {
        return new TaxonTranslation();
    }

instead

    public static function getTranslationClass()
    {
        return TaxonTranslation::class;
    }

in class AppBundleTaxonBundleEntityTaxon and it works.

So I think there is a bug in the documentation http://docs.sylius.org/en/latest/customization/model.html

Shouldn't \Sylius\Component\Taxonomy\Model\Taxon::createTranslation make use of method static::getTranslationClass? I think it then follows the documentation, makes the static method useful and doesn't introduce BC anywhere. Else the static can be moved out and createTranslation has to be overridden as @lasotaartur showed.

@Zales0123 @pjedrzejewski Your thoughts on this? Can submit a PR to fix it everywhere if this is the best way to solve this.

Easiest fix (and can confirm it works as @lasotaartur did) is overriding the method and removing the static method call. Then it only requires adjusting the docs to make it work again. I have the impression the static method call is not used anywhere anyway and it doesn't feel like often used in Sylius (static method calls).

Sorry to bump this but I would agree with @stefandoorn here. Our use case is an extended ProductTranslation class which works as expected but when installing fixtures we are forced to also extend the Product class to adapt the createTranslation method. Would this benefit from a PR @pjedrzejewski?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mezoni picture mezoni  路  3Comments

reyostallenberg picture reyostallenberg  路  3Comments

loic425 picture loic425  路  3Comments

inssein picture inssein  路  3Comments

mikemix picture mikemix  路  3Comments