What is happening seems to be incorrect hydration of a partial result.

This is usually a problem with queries like following:

SELECT a, b FROM A a JOIN a.b b WHERE b.something = 123;

This query will select all A records with all its a.b populated, but will
filter them by a restriction. The problem is that this will hydrate a
partial graph into your object, and that object will afterwards remain in
memory, broken until you clear the UnitOfWork.

The fix is to not join in records and filter:

SELECT a, b FROM A a LEFT JOIN a.b b JOIN a.b b2 WHERE b2.something = 123;

In your case, the filtering is subtle because you used a JOIN condition
twice, and that implicitly acts as restriction.

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

On Fri, Dec 29, 2017 at 3:24 PM, <[email protected]> wrote:

> 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>
>
> --
> You received this message because you are subscribed to the Google Groups
> "doctrine-user" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at https://groups.google.com/group/doctrine-user.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"doctrine-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/doctrine-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to