Doctrine Inheritance: Discriminator from Entity attribute and not table column?

Doctrine Inheritance: Discriminator from Entity attribute and not table column?



Using Doctrine2 inheritance, I want a slight variation so that the discriminator is not based on a column (from the mapped table), but rather on an Entity's attribute. The code would look like this:



(p.s I know there's nothing like @DiscriminatorAttribute in Doctrine, I'm just asking about an eventual workaround to "implement it")


<?php

namespace AppEntity;

use DoctrineORMMapping as ORM;

/**
* @Entity
* @InheritanceType("SINGLE_TABLE")
* @DiscriminatorAttribute(name="shopType", type="string")
* @DiscriminatorMap("local" = "LocalShop", "foreign" = "ForeignShop")
*/
class Shop

const TYPE_LOCAL="local";
const TYPE_FOREIGN="foreign";

protected $shopType;
// ...


/**
* @Entity
*/
class LocalShop extends Shop

public function __construct()

$this->shopType=Shop::TYPE_LOCAL;

// ...

/**
* @Entity
*/
class ForeignShop extends Shop

public function __construct()

$this->shopType=Shop::TYPE_FOREIGN;

// ...






Why would you want this? It'd be a million times neater (& less coupled) to simply add a method shopType() which returns either of those constants.

– Stratadox
Sep 13 '18 at 23:09






I'm working on a huge old DB with lots of legacy inside, and the logic from each ShopType is completely different. So I'm seeking to hide this chaos through ORM, a step behind further migration to a neat DB..

– medunes
Sep 13 '18 at 23:12






In that case, at the very least I'd map the property as, well, property. After that you could check if you can simply make the column it's mapped to, the discriminator column. If doctrine does not allow doing that, add a custom migration that duplicates the column contents and weep :)

– Stratadox
Sep 13 '18 at 23:18






Sounds rational, that's what first came to my mind among other solutions. The constraint is I SHALL NOT write any migrations or change anything regarding the current DB architecture.

– medunes
Sep 13 '18 at 23:21






As far as the why goes, the Doctrine ORM was designed for simple CRUD type databases. Complex legacy stuff is pretty much off the table. Too many variations to try and support.

– Cerad
Sep 14 '18 at 15:42




1 Answer
1



Given the fact that shopType is a rather static property (in the sense that it will always be the same for all instances of a class) you can simply define the shopType as default for the property, and use the existing column as discriminator column:


shopType


shopType


<?php

namespace AppEntity;

use DoctrineORMMapping as ORM;

/**
* @ORMEntity
* @ORMInheritanceType("SINGLE_TABLE")
* @ORMDiscriminatorColumn(name="shopType", type="string")
* @ORMDiscriminatorMap("local" = "LocalShop", "foreign" = "ForeignShop")
*/
class Shop

protected const TYPE_LOCAL = 'local';
protected const TYPE_FOREIGN = 'foreign';

// ...


/**
* @Entity
*/
class LocalShop extends Shop

protected $shopType = Shop::TYPE_LOCAL;
// ...


/**
* @Entity
*/
class ForeignShop extends Shop

protected $shopType = Shop::TYPE_FOREIGN;
// ...



Doctrine's hydrators will take a new instance of your class, which gets instantiated with all default values applied, and then write all the fetched information from the database to the mapped properties.



Since your property has the expected value in the defaults, and is not mapped, its correct default value will not be changed by the hydration process and have the expected value, even when fetched from the database.



In that process, the constructor is not called (Entities are either cloned or produced by Reflection's newInstanceWithoutConstructor), which is why the original code did not work.



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)