Skip to content

Loading…

DDC-1776: Abstract class marked as @Entity in a single table inheritance is wrongly hydrated #2428

Closed
doctrinebot opened this Issue · 6 comments

2 participants

@doctrinebot

Jira issue originally created by user benjamin:

I have the following entity hierarchy:

/****
 * @Entity
 * @InheritanceType("SINGLE_TABLE")
 * @DiscriminatorColumn(name="type", type="string")
 * @DiscriminatorMap({
     "prospectEdited" = "Application\Domain\Model\Event\ProspectEditedEvent"
   })
 */
abstract class Event {
    // ...
}

/****
 * @Entity
 */
abstract class ProspectEvent extends Event {
    /****
     * @ManyToOne(targetEntity="Application\Domain\Model\Prospect")
     */
    protected $prospect;
}

/****
 * @Entity
 */
class ProspectEditedEvent extends ProspectEvent {
    // ...
}

Although ProspectEvent is an abstract class, I need to mark it as @Entity, so that I can query for any type of ProspectEvent:

SELECT e FROM ProspectEvent e WHERE e.prospect = ?

So far, so good.
The problem happens when I query the root class:

SELECT e FROM Event e

The query works fine, but the returned ProspectEvent entities have a NULL $prospect property.
I noticed that in that case, the DocBlock for $prospect is totally ignored (a wrong @JoinColumn name for example, doesn't throw an exception).

The workaround to make it work, is to add a "fake" entry to the discriminator map for the abstract class:

@DiscriminatorMap({
  "prospectEvent"  = "Application\Domain\Model\Event\ProspectEvent"
  "prospectEdited" = "Application\Domain\Model\Event\ProspectEditedEvent"
})

Even though there is no such "prospectEvent" discriminator entry possible, as the class is abstract.
Final point, if I remove the @Entity DocBlock on ProspectEvent, $prospect is hydrated correctly, but then it is not possible to issue a DQL query on ProspectEvent anymore.

@doctrinebot

Comment created by benjamin:

Any feedback?

@doctrinebot

Comment created by @ocramius:

[~benjamin] I'd say this has to be fixed in validation. What if we enforce the fake discriminator map? The "workaround" you suggested is actually what you should write with correct mappings.

@doctrinebot

Comment created by @ocramius:

Yes, this has to be reported in validation somehow. The "workaround" is not actually a workaround, but what is expected to be written by the developer.

@doctrinebot

Comment created by benjamin:

Ok, I found this weird because it's impossible to store a ProspectEvent in the database (as it's abstract), so adding a discriminator entry for it looks weird to me.
I would then suggest one of these two approaches:

  • Either remove the requirement to have a discriminator entry for the parent class if it's abstract (this would be my preference). ** Or, document this behavior, and* throw a proper exception if we try to persist / query such a hierarchy of classes.

But leaving the error unreported, and instantiating incomplete objects, is a real danger!

@doctrinebot

Comment created by @beberlei:

We fixed errors of this kind a while ago

@doctrinebot

Issue was closed with resolution "Duplicate"

@Ocramius Ocramius 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.