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

Closed
doctrinebot opened this Issue Jan 15, 2013 · 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 Dec 6, 2015
@doctrinebot doctrinebot closed this Dec 6, 2015
@doctrinebot doctrinebot added the Bug label Dec 7, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment