Search code examples
symfonydoctrinediscriminatorclass-table-inheritance

Query on Doctrine class table inheritance with required fields


My domain has a parent IncidenceMessage class and several child classes (i.e. IncidenceMessageText). I have the following class table inheritance configuration:

Domain\Model\IncidenceMessage\IncidenceMessage:
    type: entity
    repositoryClass: Infrastructure\Domain\Model\IncidenceMessage\DoctrineIncidenceMessageRepository
    table: incidence_messages
    inheritanceType: JOINED
    discriminatorColumn:
        name: type
        type: string
        length: 30
    discriminatorMap:
        text: IncidenceMessageText
        image: IncidenceMessageImage
        audio: IncidenceMessageAudio
        video: IncidenceMessageVideo
    fields:
        ...

I can create any IncidenceMessage entity correctly.

Having only a IncidenceMessageText in database, when I try to fetch incidence messages I get the following error:

TypeError: Argument 1 passed to Domain\Model\File\FileId::__construct() must be of the type string, null given

(FileId is a value object that represents the id of a File entity)

IncidenceMessageImage has a File field that is a foreign key and it is required.

It makes no sense to me that Doctrine fetches File when IncidenceMessageText doesn't have that field.

While debugging, I discovered that doctrine does a SELECT with LEFT JOINs with every single IncidenceMessage table and this calls my FileTypeId::convertToPHPValue method:

class FileIdType extends Type
{
    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        return new FileId($value);
    }
}

AFAIK, the problem here is that child classes have required fields but that shouldn't be a stopper, right?


Solution

  • I found a possible workaround. On my custom DBAL Type FileIdType, I checked if the value was null before instantiating FileId:

    use Doctrine\DBAL\Types\Type;
    
    class FileIdType extends Type
    {
        public function convertToPHPValue($value, AbstractPlatform $platform)
        {
            return $value ? new FileId($value) : null;
        }
    }