[DDC-3386] Multiple Level Discriminator Mapping Created: 11/Nov/14  Updated: 18/Nov/14

Status: Reopened
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4.6
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Patrick Rose Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: inheritance, mapping, orm

Linux, PHP 5.5.9


We currently have a situation where we're required to have up to 4 levels of discriminator mappings, and we're finding that Doctrine will insert into our root entity table, and the leaf entity table correctly. However, the tables in between are not being set at all.

The hierarchy is below:

Deal -> EcommerceDeal
Deal -> EcommerceDeal -> ItemSpecific
Deal -> EcommerceDeal -> ItemSpecific -> ItemSpecificScheduled
Deal -> EcommerceDeal -> DealSet -> SetCombo
Deal -> EcommerceDeal -> DealSet -> SetMoreForLess

When inserting an ItemSpecific entity, I found that the Deal and ItemSpecific tables were filled but the EcommerceDeal was not.

There's not much documentation about trees that are slightly more complicated than the Employee, Person, Admin example in the docs so there's a chance I've misunderstood how to build the tables correctly.

Currently we only have one discriminator column on the Deal table. Should we instead be setting up several columns that are nullable and setting new discriminator columns further down the tree?

EDIT: All classes are Class Table Inheritance, in case that is unclear

Comment by Patrick Rose [ 11/Nov/14 ]

The thing that always confuses me while I'm working on this is the fact that I can select from the Database fine. I've got dummy data in each table and Doctrine is clever enough to select all the correct fields from the correct tables so I'm unsure whether I've made a mistake or if Doctrine has a bug.

Comment by Marco Pivetta [ 11/Nov/14 ]

This looks like normal ORM behavior to me, not really requiring any change. What's the reason for inserts on the other tables?

Comment by Patrick Rose [ 12/Nov/14 ]

We have data that's the same across all Ecommerce Deal types (things like the start time, end time etc). I'd expect to be able to set all the values on (say) an ItemSpecific deal and Doctrine to insert the generic data in the EcommerceDeal table.

Comment by Patrick Rose [ 12/Nov/14 ]

It turns out that Doctrine does support this out of the box. A predecessor had overriden the JoinedSubclassPersister with the sole purpose being to comment out the section relating to discriminator columns.

Comment by Patrick Rose [ 12/Nov/14 ]

Problem is with an overridden method not in the Doctrine core.

Comment by Marco Pivetta [ 13/Nov/14 ]

Patrick Rose do you mean that your version (local file) of the JoinedSubclassPersister was monkey-patched?

Comment by Patrick Rose [ 13/Nov/14 ]

Undoing monkey patch does not fully fix issue

Comment by Patrick Rose [ 13/Nov/14 ]

Marco: We'd overridden a whole bunch of classes to do various things, but I've got no idea what those were (these happened at least 6 months before I joined).

The JoinedSubclassPersister was overridden and just commented out two lines

$tableAlias = ($this->class->rootEntityName == $this->class->name) ? $baseTableAlias : $this->getSQLTableAlias($this->class->rootEntityName);
$columnList[] = $tableAlias . '.' . $discrColumn;

From speaking to people, it seems that the point of using that was to allow the discriminator columns to be on the incorrect tables.

However, even with undoing this, I've just tried to create a ComboDeal and it inserted into the root table and the leaf table but none of the other tables. However it looks like ItemSpecific entities are fine. I'll just retry creation of each entity type and get back to you.

Comment by Patrick Rose [ 13/Nov/14 ]

Just finished doing that. I can create EcommerceDeal entities, and ItemSpecific entities and they'll insert into the correct tables (so the EcommerceDeal entity saves into the EcommerceDeal and Deal tables, and the ItemSpecific entity saves into the ItemSpecific, EcommerceDeal and Deal tables).

The rest only insert into the Deal table and the table relating to that class.

Comment by Patrick Rose [ 18/Nov/14 ]

Is there an update on how we can resolve this?

Comment by Patrick Rose [ 18/Nov/14 ]

We've spent a day looking through and trying to work out what seems to be happening and seem to have a resolution.

It appears that the method of getting the parents was only getting those which weren't transient (and thus were entities), which in our case wasn't working since then Doctrine complains about duplicate column definitions. After overriding the getParentClass to allow us to be explicit we got it to work.

Generated at Sun Oct 04 03:37:52 EDT 2015 using JIRA 6.4.10#64025-sha1:5b8b74079161cd76a20ab66dda52747ee6701bd6.