Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

doctrine targetEntity interfaces

I am trying to use interfaces as "targetEntity". The simple code should explain what I intend to do

Interface:

namespace Project\Entity;

interface AnimalInterface{


}

Cat:

namespace Project\Entity;
use Doctrine\ORM\Mapping as ORM;
use Project\Entity\AnimalInterface;

/**
 * Represents an Invoice.
 *
 * @ORM\Entity
 * @ORM\Table(name="Cat")
 */
class Cat implements AnimalInterface  {

     /**
     * @var int
     * @ORM\Id @ORM\Column(type="integer", name="id")
     * @ORM\GeneratedValue
     */
     protected $id;
}

Dog:

namespace Project\Entity;
use Doctrine\ORM\Mapping as ORM;
use Project\Entity\AnimalInterface;

/**
 * @ORM\Entity
 * @ORM\Table(name="Dog")
 */
class Dog implements AnimalInterface  {

     /**
     * @var int
     * @ORM\Id @ORM\Column(type="integer", name="id")
     * @ORM\GeneratedValue
     */
     protected $id;
}

AnimalFarm (can just contain one animal ;)):

 namespace Project\Entity;
 use Doctrine\ORM\Mapping as ORM;

 /**
 * @ORM\Entity
 * @ORM\Table(name="AnimalFarm")
 */
class AnimalFarm  {
    /**
     *
     * @var int
     * @ORM\Id @ORM\Column(type="integer", name="id")
     * @ORM\GeneratedValue
     */
     protected $id;

     /**
     * @ORM\ManyToOne(targetEntity="Project\Entity\AnimalInterface")
     * @var AnimalInterface
     */
     protected $animal;


     public function setAnimal(AnimalInterface $animal){
         $this->animal = $animal;
     }
}

I'm using the TargetEntityResolver as specified here -> http://symfony.com/doc/master/cookbook/doctrine/resolve_target_entity.html

bootstrap.php (Zend) :

    $em = $doctrine->getEntityManager();
    $evm = $em->getEventManager();

    $listener = new  \Doctrine\ORM\Tools\ResolveTargetEntityListener();
    $listener->addResolveTargetEntity(
            'Project\Entity\AnimalInterface',
            'Project\Entity\Dog',
            array()
    );
    $listener->addResolveTargetEntity(
            'Project\Entity\AnimalInterface',
            'Project\Entity\Cat',
            array()
    );
    $evm->addEventListener(Doctrine\ORM\Events::loadClassMetadata, $listener);

It seems the Resolver can only resolve one Entity to an interface, the first given one. In this example cat. Doctrine build the table AnimalFarm with an relationship (foreignkey) to the table dog. When I'm trying to add a dog to the table via the EntityManager Doctrine fails with following ErrorMessage: Uncaught exception 'Doctrine\ORM\ORMException' with message 'Found entity of type Project\Entity\Dog on association Project\Entity\AnimalFarm#animal, but expecting Project\Entity\Cat' in [...]

Seems like it's not possible to define multiple targetEntities via an Interface?

I don't want to use inheritance because Entities could implement multiple interfaces. (Multiple inheritance not possible)

Any ideas?

Maybe good searching keywords I can look for?

Thanks very much.

like image 517
roccosportal.com Avatar asked Jan 16 '13 13:01

roccosportal.com


1 Answers

This is taken from doctrine2 docs. You can only resolve one object using this method.

/**
 * An interface that the invoice Subject object should implement.
 * In most circumstances, only a single object should implement
 * this interface as the ResolveTargetEntityListener can only
 * change the target to a single object.
 */
interface InvoiceSubjectInterface
{
    // List any additional methods that your InvoiceModule
    // will need to access on the subject so that you can
    // be sure that you have access to those methods.

    /**
     * @return string
     */
    public function getName();
}
like image 103
htm01 Avatar answered Sep 26 '22 23:09

htm01