Subentities with discriminator column in query result #5832

Open
opened 2026-01-22 15:19:10 +01:00 by admin · 1 comment
Owner

Originally created by @fasterforward on GitHub (Jan 8, 2018).

Originally assigned to: @fasterforward on GitHub.

We have some problems querying an entity with embedded sub entities. First let me sketch the context:

  • We have a table with Offer entities
  • Each Offer consists of multiple Offerlines
  • Each Offerline has one related Generalassuranceline
  • Each Generalassuranceline has one related Possession
    • This Possession has a discriminator column defined to distinguish two possession subtypes: Vehicle and Misc

In the mapping of Generalassuranceline the Possession is defined as a many-to-one relation (named 'object') to the generic Possession type, because at the Generalassuranceline level the 'object' can be either a Vehicle or a Misc entity.

(The detailed mappings of the entities are listed below.)

The DQL query we execute is the following:

SELECT
    offer,
    offerline,
    generalassuranceline
FROM
    Entity\Offer\Offer offer
    INNER JOIN offer.offerlines offerline
    INNER JOIN offerline.generalassuranceline generalassuranceline
WHERE
    offer.id = 6749

Problem:
In the database, the offer we query has two offerlines. In the following situations, the output is generated by:

\Doctrine\Common\Util\Debug::dump($query->getResult(), 3);

Situation 1:
If we specify the "object" relation in Generalassuranceline as type Possession, we only get one offerline entity in our result.

array(1) {
  [0]=>
  object(stdClass)#27 (5) {
    ["__CLASS__"]=>
    string(18) "Entity\Offer\Offer"
    ["id"]=>
    int(6749)
    ["offernumber"]=>
    string(8) "98037192"
    ["description"]=>
    string(13) "auto 29-KQB-3"
    ["offerlines"]=>
    array(1) {
      [0]=>
      string(22) "Entity\Offer\Offerline"
    }
  }
}

Situation 2:
If we specify the "object" relation in Generalassuranceline as type Vehicle, we get both the offerline entities as expected.

array(1) {
  [0]=>
  object(stdClass)#27 (5) {
    ["__CLASS__"]=>
    string(18) "Entity\Offer\Offer"
    ["id"]=>
    int(6749)
    ["offernumber"]=>
    string(8) "98037192"
    ["description"]=>
    string(13) "auto 29-KQB-3"
    ["offerlines"]=>
    array(2) {
      [0]=>
      string(22) "Entity\Offer\Offerline"
      [1]=>
      string(22) "Entity\Offer\Offerline"
    }
  }
}

Can someone explain to us the reason why we get only one offerline entity in the offer result in situation 1 and what we can change to retrieve more reliable results?

Mappings:

Offer

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping
    xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

  <entity name="Entity\Offer\Offer" table="accountingoffer">

    <id name="id" type="integer" column="id">
        <generator strategy="IDENTITY"/>
    </id>

    <field name="offernumber" type="string" column="offernumber" length="255" nullable="true" />
    <field name="description" type="string" column="description" length="255" nullable="true" />

    <one-to-many field="offerlines" target-entity="Entity\Offer\Offerline" mapped-by="offer" fetch="LAZY" />
  </entity>
</doctrine-mapping>

Offerline

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping
    xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

  <entity name="Entity\Offer\Offerline" table="accountingofferline">

    <id name="id" type="integer" column="id">
        <generator strategy="IDENTITY"/>
    </id>

    <field name="offernumber" type="string" column="offernumber" length="255" nullable="true" />

    <many-to-one field="offer" target-entity="Entity\Offer\Offer" inversed-by="offerlines">
        <join-column name="accountingoffer_id" referenced-column-name="id"/>
    </many-to-one>

    <one-to-one field="generalassuranceline" target-entity="Entity\Offer\Generalassuranceline" mapped-by="offerline" />
  </entity>
</doctrine-mapping>

Generalassuranceline

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping
    xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

  <entity name="Entity\Offer\Generalassuranceline" table="accountingofferline_generalassurance">

    <id name="offerlineId" type="integer" column="accountingofferline_id">
        <generator strategy="IDENTITY"/>
    </id>

    <one-to-one field="offerline" target-entity="Entity\Offer\Offerline" inversed-by="generalassuranceline">
        <join-column name="accountingofferline_id" referenced-column-name="id"/>
    </one-to-one>

    <many-to-one field="object" target-entity="Entity\Possession\Possession" fetch="LAZY">
        <join-column name="crmpossession_id" referenced-column-name="id"/>
    </many-to-one>
  </entity>
</doctrine-mapping>

Possession

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping
    xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

  <entity name="Entity\Possession\Possession" table="crmpossession" inheritance-type="SINGLE_TABLE">

    <id name="id" type="integer" column="id">
        <generator strategy="IDENTITY"/>
    </id>

    <discriminator-column name="crmpossessiontypecategory_id" type="integer" />
    <discriminator-map>
        <discriminator-mapping value="1" class="Entity\Possession\Vehicle" />
        <discriminator-mapping value="2" class="Entity\Possession\Misc" />
    </discriminator-map>

    <field name="description" type="string" column="description" length="255" nullable="true" />
  </entity>
</doctrine-mapping>

Vehicle

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping
    xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

  <entity name="Entity\Possession\Vehicle" />

</doctrine-mapping>

Misc

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping
    xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

  <entity name="Entity\Possession\Misc" />

</doctrine-mapping>
Originally created by @fasterforward on GitHub (Jan 8, 2018). Originally assigned to: @fasterforward on GitHub. We have some problems querying an entity with embedded sub entities. First let me sketch the context: - We have a table with **Offer** entities - Each **Offer** consists of multiple **Offerlines** - Each **Offerline** has one related **Generalassuranceline** - Each **Generalassuranceline** has one related **Possession** - This **Possession** has a discriminator column defined to distinguish two possession subtypes: **Vehicle** and **Misc** In the mapping of **Generalassuranceline** the **Possession** is defined as a many-to-one relation (named 'object') to the generic **Possession** type, because at the **Generalassuranceline** level the 'object' can be either a **Vehicle** or a **Misc** entity. (The detailed mappings of the entities are listed below.) The DQL query we execute is the following: ```sql SELECT offer, offerline, generalassuranceline FROM Entity\Offer\Offer offer INNER JOIN offer.offerlines offerline INNER JOIN offerline.generalassuranceline generalassuranceline WHERE offer.id = 6749 ``` **Problem:** In the database, the **offer** we query has two **offerlines**. In the following situations, the output is generated by: `\Doctrine\Common\Util\Debug::dump($query->getResult(), 3);` Situation 1: If we specify the "object" relation in **Generalassuranceline** as type **Possession**, we only get _one_ **offerline** entity in our result. ```php array(1) { [0]=> object(stdClass)#27 (5) { ["__CLASS__"]=> string(18) "Entity\Offer\Offer" ["id"]=> int(6749) ["offernumber"]=> string(8) "98037192" ["description"]=> string(13) "auto 29-KQB-3" ["offerlines"]=> array(1) { [0]=> string(22) "Entity\Offer\Offerline" } } } ``` Situation 2: If we specify the "object" relation in **Generalassuranceline** as type **Vehicle**, we get _both_ the **offerline** entities as expected. ```php array(1) { [0]=> object(stdClass)#27 (5) { ["__CLASS__"]=> string(18) "Entity\Offer\Offer" ["id"]=> int(6749) ["offernumber"]=> string(8) "98037192" ["description"]=> string(13) "auto 29-KQB-3" ["offerlines"]=> array(2) { [0]=> string(22) "Entity\Offer\Offerline" [1]=> string(22) "Entity\Offer\Offerline" } } } ``` Can someone explain to us the reason why we get only one **offerline** entity in the **offer** result in situation 1 and what we can change to retrieve more reliable results? **Mappings:** **Offer** ```xml <?xml version="1.0" encoding="utf-8"?> <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <entity name="Entity\Offer\Offer" table="accountingoffer"> <id name="id" type="integer" column="id"> <generator strategy="IDENTITY"/> </id> <field name="offernumber" type="string" column="offernumber" length="255" nullable="true" /> <field name="description" type="string" column="description" length="255" nullable="true" /> <one-to-many field="offerlines" target-entity="Entity\Offer\Offerline" mapped-by="offer" fetch="LAZY" /> </entity> </doctrine-mapping> ``` **Offerline** ```xml <?xml version="1.0" encoding="utf-8"?> <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <entity name="Entity\Offer\Offerline" table="accountingofferline"> <id name="id" type="integer" column="id"> <generator strategy="IDENTITY"/> </id> <field name="offernumber" type="string" column="offernumber" length="255" nullable="true" /> <many-to-one field="offer" target-entity="Entity\Offer\Offer" inversed-by="offerlines"> <join-column name="accountingoffer_id" referenced-column-name="id"/> </many-to-one> <one-to-one field="generalassuranceline" target-entity="Entity\Offer\Generalassuranceline" mapped-by="offerline" /> </entity> </doctrine-mapping> ``` **Generalassuranceline** ```xml <?xml version="1.0" encoding="utf-8"?> <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <entity name="Entity\Offer\Generalassuranceline" table="accountingofferline_generalassurance"> <id name="offerlineId" type="integer" column="accountingofferline_id"> <generator strategy="IDENTITY"/> </id> <one-to-one field="offerline" target-entity="Entity\Offer\Offerline" inversed-by="generalassuranceline"> <join-column name="accountingofferline_id" referenced-column-name="id"/> </one-to-one> <many-to-one field="object" target-entity="Entity\Possession\Possession" fetch="LAZY"> <join-column name="crmpossession_id" referenced-column-name="id"/> </many-to-one> </entity> </doctrine-mapping> ``` **Possession** ```xml <?xml version="1.0" encoding="utf-8"?> <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <entity name="Entity\Possession\Possession" table="crmpossession" inheritance-type="SINGLE_TABLE"> <id name="id" type="integer" column="id"> <generator strategy="IDENTITY"/> </id> <discriminator-column name="crmpossessiontypecategory_id" type="integer" /> <discriminator-map> <discriminator-mapping value="1" class="Entity\Possession\Vehicle" /> <discriminator-mapping value="2" class="Entity\Possession\Misc" /> </discriminator-map> <field name="description" type="string" column="description" length="255" nullable="true" /> </entity> </doctrine-mapping> ``` **Vehicle** ```xml <?xml version="1.0" encoding="utf-8"?> <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <entity name="Entity\Possession\Vehicle" /> </doctrine-mapping> ``` **Misc** ```xml <?xml version="1.0" encoding="utf-8"?> <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <entity name="Entity\Possession\Misc" /> </doctrine-mapping> ```
admin added the BugMissing Tests labels 2026-01-22 15:19:10 +01:00
Author
Owner

@lcobucci commented on GitHub (Feb 22, 2018):

@fasterforward this seems a bit odd, could you please send us a failing test case that reproduces that behaviour? It would help us a lot to identify and fix the issue you're describing.

Since it's a bug you can use 2.6 as base and we'll port it to master when/if needed.

You can find examples on 388afb46d0/tests/Doctrine/Tests/ORM/Functional/Ticket

@lcobucci commented on GitHub (Feb 22, 2018): @fasterforward this seems a bit odd, could you please send us a failing test case that reproduces that behaviour? It would help us a lot to identify and fix the issue you're describing. Since it's a bug you can use `2.6` as base and we'll port it to `master` when/if needed. You can find examples on https://github.com/doctrine/doctrine2/tree/388afb46d0cb3ed0c51332e8df0de9e942c2690b/tests/Doctrine/Tests/ORM/Functional/Ticket
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5832