Hey,
I 've got an issue with aggregating entities in Doctrine ORM 2.x. I 've seen the ResolveTargetEntityListener
solution provided by Doctrine. This seems to work for exactly one abstraction as seen in the Doctrine documentation. But what if I have more than one inheritation from an abstract entity or more than one implementation of an interface?
A short example …
declare(strict_types=1);
namespace Application\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\MappedSuperclass
*/
abstract class Partner
{
/**
* @ORM\Column(name="name", type="string", length=255, nullable=false)
*/
protected ?string $name;
}
As you can see, this is the abstract entity from which other entities will derive. The inherited entities are somewhat like the following two. For the example, I will mention only two. There are far more entities.
declare(strict_types=1);
namespace Application\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Represents a natural person
*
* @ORM\Entity
* @ORM\Table(name="natural_person")
*/
class NatualPerson extends Partner
{
/**
* @var int
* @ORM\Id @ORM\Column(type="integer", name="id")
* @ORM\GeneratedValue
*/
protected int $id;
}
… and the other one …
declare(strict_types=1);
namespace Application\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Represents a legal person (companies)
*
* @ORM\Entity
* @ORM\Table(name="legal_person")
*/
class LegalPerson extends Partner
{
/**
* @var int
* @ORM\Id @ORM\Column(type="integer", name="id")
* @ORM\GeneratedValue
*/
protected int $id;
}
A group can contain zero or more partners. A collection of natural and legal persons.
declare(strict_types=1);
namespace Application\Entity;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="group")
*/
class Group
{
/**
*
* @var int
* @ORM\Id @ORM\Column(type="integer", name="id")
* @ORM\GeneratedValue
*/
protected $id;
/**
* @ORM\ManyToOne(targetEntity="Application\Entity\Partner")
* @var Partner
*/
protected Collection $members;
public function __construct()
{
$this->members = new ArrayCollection();
}
}
If I 'm using the example from the above mentioned doctrine cookbook example, this won 't work.
$evm = new \Doctrine\Common\EventManager;
$rtel = new \Doctrine\ORM\Tools\ResolveTargetEntityListener;
// Adds a target-entity class
$rtel->addResolveTargetEntity(Partner::class, LegalPerson::class, []);
$rtel->addResolveTargetEntity(Partner::class, NaturalPerson::class, []);
// Add the ResolveTargetEntityListener
$evm->addEventListener(Doctrine\ORM\Events::loadClassMetadata, $rtel);
$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config, $evm);
Question: Is there another smart way to reach something like aggregation based on an abstract entity or an interface, that aggregates to more than one target entity?