A subclass of a class as its extended parent

I created the following abstract class that uses unidirectional table inheritance and maps subclasses to the DiscriminatorColumn model .

 /** * @Entity * @Table(name="entity") * @InheritanceType("SINGLE_TABLE") * @DiscriminatorColumn(name="model", type="string") * @DiscriminatorMap({ * "green" = "model\GreenEntity", * "blue" = "model\BlueEntity" * }) */ abstract class AbstractEntity { /** @Id @Column(type="string") */ protected $entity_id; } 

Let's say I extend the AbstractEntity abstract class to some classes:

 class GreenEntity extends AbstractEntity {} class BlueEntity extends AbstractEntity {} 

And expand them with a few more subclasses

 class GreenEntityChildOne extends GreenEntity {} class GreenEntityChildTwo extends GreenEntity {} class BlueEntityChildOne extends BlueEntity {} class BlueEntityChildTwo extends BlueEntity {} 

Now, for example, when I create an instance of GreenEntityChildOne and store it in the database, it throws an exception that I do not have for it.

I am trying to make GreenEntityChildOne appear as GreenEntity (or rather, every class that extends a class below AbstractEntity is displayed as a class that extends an upper abstract class).

Is it possible?

+7
oop php orm doctrine2 discriminator
source share
2 answers

This is not possible with pure annotations.

Yes, the comparison you are trying to achieve is possible. However, not with pure annotations. The important thing is that the Doctrine must know the subclass of all at runtime. If you do not want to specify them explicitly in the annotations of the associated superclass, you will need to dynamically provide them.

Doctrine Event System to the rescue

There is a dynamic mapping to Doctrine that explains how you can use Doctrine event listeners to programmatically change the loaded ClassMetadata . To dynamically add subclasses to the discriminator map, you can implement the Doctrine event receiver as follows:

 class DynamicDiscriminatorMapSubscriber implements EventSubscriber { public function getSubscribedEvents() { return array(Events::loadClassMetadata); } public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs) { $metadata = $eventArgs->getClassMetadata(); $metadata->addDiscriminatorMapClass("GreenEntityChildOne", GreenEntityChildOne::class); } } 

Register your subscriber

Now you only need to register an event subscriber with Doctrine. Ideally, you add the classes you want to add based on your configuration for the event subscriber.

 // create dynamic subscriber based on your config which contains the classes to be mapped $subscriber = new DynamicDiscriminatorMapSubscriber($config); $entityManager->getEventManager()->addEventSubscriber($subscriber); 

Further reading

Also, see the PHP mapping section of the Doctrine manual and the more informative docs API for ClassMetadataBuilder .

+1
source share

The answer is possibly in the Doctrine docs:

"All feature classes that are part of the hierarchy of mapped features (including the topmost class) must be specified in @DiscriminatorMap"

http://doctrine-orm.readthedocs.org/en/latest/reference/inheritance-mapping.html

You specified only GreenEntity and BlueEntity.

I don’t know what I'm talking about. This is the first thing I've ever read about Doctrine ...

0
source share

All Articles