3

Is it possible to override @ManyToOne(targetEntity)?

I read this Doctrine documentation page, but it doesn't mention how to override targetEntity.

Here's my code:

namespace AppBundle\Model\Order\Entity;

use AppBundle\Model\Base\Entity\Identifier;
use AppBundle\Model\Base\Entity\Product;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\AttributeOverrides;
use Doctrine\ORM\Mapping\AttributeOverride;

/**
 * Class OrderItem
 *
 *
 * @ORM\Entity
 * @ORM\Table(name="sylius_order_item")
 * @ORM\AssociationOverrides({
 *      @ORM\AssociationOverride(
 *          name="variant",
 *          joinColumns=@ORM\JoinColumn(
 *              name="variant", referencedColumnName="id", nullable=true
 *          )
 *      )
 * })
 */
class OrderItem extends \Sylius\Component\Core\Model\OrderItem
{

    /**
     * @var
     * @ORM\ManyToOne(targetEntity="AppBundle\Model\Base\Entity\Product")
     */
    protected $product;

    /**
     * @return mixed
     */
    public function getProduct()
    {
        return $this->product;
    }

    /**
     * @param mixed $product
     */
    public function setProduct($product)
    {
        $this->product = $product;
    }
}

I was able to to override the definition for the "variant" column and set this column to null, but I can't figure it out how to change the targetEntity.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
lukas_jenicek
  • 66
  • 2
  • 3

2 Answers2

3

As described in the doc, you cannot change the type of your association: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html#association-override

BUT, you can define a targetEntity as an interface (that's the default sylius conf it seems),

targetEntity="AppBundle\Entity\ProductInterface"

Extends the original one in your Interface file

namespace AppBundle\Entity;    
use Sylius\Component\Core\Model\ProductInterface as BaseProductInterface;
interface ProductInterface extends BaseProductInterface {}

And add the mapping in your configuration

doctrine:
    orm:
        resolve_target_entities:
            AppBundle\Entity\ProductInterface: AppBundle\Entity\Product

It's described here: http://symfony.com/doc/current/doctrine/resolve_target_entity.html

Hope it helps

ylastapis
  • 150
  • 5
0

I didn't find a way to override the targetEntity value of an association when using annotations, but it is possible when using PHP mapping (php or staticphp in Symfony).

https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/php-mapping.html

We can create a function:

function updateAssociationTargetEntity(ClassMetadata $metadata, $association, $targetEntity)
{
    if (!isset($metadata->associationMappings[$association])) {
        throw new \LogicException("Association $association not defined on $metadata->name");
    }
    $metadata->associationMappings[$association]['targetEntity'] = $targetEntity;
}

and use it like this:

updateAssociationTargetEntity($metadata, 'product', AppBundle\Model\Base\Entity\Product::class);

That way, when Doctrine loads the metadata for the class AppBundle\Model\Order\Entity\OrderItem, it first loads the parent (\Sylius\Component\Core\Model\OrderItem) metadata, and then it loads the PHP mapping for the child class where we override the association mapping that was set when loading the parent class metadata.

Jetyu
  • 1