Shopsys: Extending of *Translation entities is not possible

Created on 9 Jan 2019  路  3Comments  路  Source: shopsys/shopsys

What is happening

I am trying to extend TransportTranslation entity using https://github.com/shopsys/shopsys/blob/master/docs/wip_glassbox/entity-extension.md#factories documentation.

I did these steps:

I have created entity TransportTranslation in ShopBundle:
<?php
namespace Shopsys\ShopBundle\Model\Transport;
use Doctrine\ORM\Mapping as ORM;
use Shopsys\FrameworkBundle\Model\Transport\TransportTranslation as BaseTransportTranslation;
/**
 * @ORM\Table(name="transport_translations")
 * @ORM\Entity
 */
class TransportTranslation extends BaseTransportTranslation
{
    /**
     * @var string
     *
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    protected $productDetailName;
    /**
     * @return string
     */
    public function getProductDetailName()
    {
        return $this->productDetailName;
    }
    /**
     * @param string $productDetailName
     */
    public function setProductDetailName($productDetailName)
    {
        $this->productDetailName = $productDetailName;
    }
}
I have registered extended entity in parameters_common.yml
shopsys.entity_extension.map:
    Shopsys\FrameworkBundle\Model\Transport\TransportTranslation: Shopsys\ShopBundle\Model\Transport\TransportTranslation
I have updated ShopBundle Transport so it looked like this:
<?php
namespace Shopsys\ShopBundle\Model\Transport;
use Doctrine\ORM\Mapping as ORM;
use Prezent\Doctrine\Translatable\Annotation as Prezent;
use Shopsys\FrameworkBundle\Model\Transport\Transport as BaseTransport;
use Shopsys\FrameworkBundle\Model\Transport\TransportData as BaseTransportData;
/**
 * @ORM\Table(name="transports")
 * @ORM\Entity
 */
class Transport extends BaseTransport
{
    /**
     * @var \Shopsys\ShopBundle\Model\Transport\TransportTranslation[]
     *
     * @Prezent\Translations(targetEntity="Shopsys\ShopBundle\Model\Transport\TransportTranslation")
     */
    protected $translations;
    /**
     * @param \Shopsys\ShopBundle\Model\Transport\TransportData $transportData
     */
    public function __construct(BaseTransportData $transportData)
    {
        parent::__construct($transportData);
    }
    /**
     * @param \Shopsys\ShopBundle\Model\Transport\TransportData $transportData
     */
    public function edit(BaseTransportData $transportData)
    {
        parent::edit($transportData);
    }
    /**
     * @return \Shopsys\ShopBundle\Model\Transport\TransportTranslation
     */
    protected function createTranslation()
    {
        return new TransportTranslation();
    }
}

What happened

Shopsys Framework > db-check-mapping:

Checking ORM mapping...
14:24:59 ERROR     [app] Doctrine\ORM\Mapping\MappingException: Duplicate definition of column 'locale' on entity 'Shopsys\ShopBundle\Model\Transport\TransportTranslation' in a field or discriminator column mapping. (uncaught exception) at /var/www/html/vendor/shopsys/doctrine-orm/lib/Doctrine/ORM/Mapping/MappingException.php line 575 while running console command `shopsys:migrations:check-mapping` ["exception" => Doctrine\ORM\Mapping\MappingException { 鈥]
14:24:59 ERROR     [console] Error thrown while running command "shopsys:migrations:check-mapping". Message: "Duplicate definition of column 'locale' on entity 'Shopsys\ShopBundle\Model\Transport\TransportTranslation' in a field or discriminator column mapping." ["exception" => Doctrine\ORM\Mapping\MappingException { 鈥,"command" => "shopsys:migrations:check-mapping","message" => "Duplicate definition of column 'locale' on entity 'Shopsys\ShopBundle\Model\Transport\TransportTranslation' in a field or discriminator column mapping."]
14:24:59 ERROR     [app] Command `shopsys:migrations:check-mapping` exited with status code 1

In MappingException.php line 575:

  [Doctrine\ORM\Mapping\MappingException]                                                                                                                  
  Duplicate definition of column 'locale' on entity 'Shopsys\ShopBundle\Model\Transport\TransportTranslation' in a field or discriminator column mapping.  

Expected result

It should not throw any error.

Hotfix

I have forked EntityExtensionParentMetadataCleanerEventSubscriber and updated condition in loadClassMetadata method like this:

if ($this->entityNameResolver->resolve($entityName) !== $entityName
    && !StringHelper::endsWith($entityName, 'Translation')
) {

In services.yml:

Shopsys\FrameworkBundle\Component\EntityExtension\EntityExtensionParentMetadataCleanerEventSubscriber:
        class: Shopsys\ShopBundle\Component\EntityExtension\EntityExtensionParentMetadataCleanerEventSubscriber
        tags:
            - { name: doctrine.event_subscriber, priority: 10 }

Created class StringHelper with a method:

/**
 * @param string $haystack
 * @param string $needle
 * @return bool
 */
public static function endsWith(string $haystack, string $needle): bool
{
    $expectedPosition = mb_strlen($haystack) - mb_strlen($needle);

    return mb_strrpos($haystack, $needle, 0) === $expectedPosition;
}
Bug

All 3 comments

@TomasLudvik Could you please provide failing test in form of PR?

@simara-svatopluk That would be super-helpful.

Hi guys, I created a failing test in #748.

Super-ugly-quick fix is to add a property protected $locale to an extended entity (without ORM annotations).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

henzigo picture henzigo  路  4Comments

simara-svatopluk picture simara-svatopluk  路  5Comments

ondrejbohac picture ondrejbohac  路  3Comments

henzigo picture henzigo  路  4Comments

boris-brtan picture boris-brtan  路  4Comments