Skip to content

Loading…

DDC-2245: EntityManager#getReference returns NULL on SINGLE_TABLE inheritance #2945

Closed
doctrinebot opened this Issue · 9 comments

2 participants

@doctrinebot

Jira issue originally created by user mak8:

When EntityManager#getReference is called with SINGLE_TABLE inherited entity, it tries to get a loaded entity by calling unitOfWork->tryGetById($sortedId, $class->rootEntityName). The call may return an entity object of root entity class which is not what is asked, then it ends up returning NULL instead of going further.

@doctrinebot

Comment created by @ocramius:

This looks quite serious. On the other side, getReference should probably call find on inheritances.

Do you have any example code for this?

@doctrinebot

Comment created by mak8:

Yes, following line returns NULL with entity classes I have(it's a part of Symfony2 project):

$entity = $em->getRepository('EnjoitechBaseBundle:MCode')->find('01') // load an entity of root entity class
$ref = $em->getReference('Enjoitech\BaseBundle\Entity\MCodeModule', '01'); // try to get reference of sub entity with same ID, this return NULL

// $ref => NULL


// MCode.php
<?php

namespace Enjoitech\BaseBundle\Entity;

use \PDO;
use Doctrine\ORM\Mapping as ORM;

/****
 * @ORM\Entity
 * @ORM\Table(name="M_CODE")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="CLASS", type="string", length=2)
 * @ORM\DiscriminatorMap({"00" = "MCode", "01" = "MCodeModule"})
 */
class MCode
{
    /****
     * @ORM\Id
     * @ORM\Column(type="string", length=2)
     */
    protected $CODE;

    /****
     * @ORM\Column(type="string", length=128)
     */
    protected $DESCRIPTION;

    public function getCODE()
    {
        return $this->CODE;
    }
}


/****
 * @ORM\Entity
 */
class MCodeModule extends MCode
{
}

I also saw a post that mentioned a similar/same issue at https://groups.google.com/forum/#!msg/doctrine-user/55IkFJlADh8/79QpCIH1Ag4J

@doctrinebot

Comment created by @beberlei:

This is the correct behavior, if you fetch MCodeModule and its "only" a MCode, then returning null is correct, because you assume to retrieve a MCodeModule or nothing.

@doctrinebot

Issue was closed with resolution "Invalid"

@doctrinebot

Comment created by mak8:

I am not assuming getReference is supposed to fetch/retrieve/load anything. Shouldn't it return a reference to an entity object even the target entity hasn't been loaded yet? getReference won't return null because you'll never know if the entity exists in database in my opinion.

@doctrinebot

Comment created by @ocramius:

[~mak8] that doesn't work with inheritances, since you will need to query the discriminator column to know what object to instantiate

@doctrinebot

Comment created by mak8:

I see, thanks for clarifying that. That was what I thought as far as I see in code; $sortedId array doesn't include discriminator column and value at all. So basically getReference won't guarantee its behaviour when the target is inheritances correct? I should rather use find() maybe. Will you keep that policy for future?

I also encountered few more issues related to SINGLE_TABLE inheritance. something like find() returns entities of other inheritance class that were loaded earlier. I needed to clear entityManager each time before I get entities of another subclassed of MCode. I guess there may be same sort of implementation without considering discriminator column. Are these all known issues or it's just how it is intended?

@doctrinebot

Comment created by @ocramius:

[~mak8] repeated calls to find give you the same instances for same identifiers. If you changed something, you'll need to clear, though it looks like you're doing a lot of unconventional stuff in there.

I think that on STI/JTI, getReference could short-circuit to find, not sure if we want it.

@doctrinebot

Comment created by mak8:

I have just one code table. PK is a combination of CLASS and CODE columns. I use CLASS column as discriminator, and CODE column is ID of each inheritance. value in CODE column won't be unique by itself in the table but I thought SINGLE_TABLE inheritance can cover that. If this structure is unconventional, I'll have to look for workaround. thanks for all your help

@beberlei beberlei was assigned by doctrinebot
@doctrinebot doctrinebot closed this
@doctrinebot doctrinebot added the Bug label
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.