[DDC-1410] leftJoin with condition WITH & Object Hydratation problem. Created: 10/Oct/11  Updated: 07/Jun/12  Resolved: 28/Oct/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: DQL, ORM
Affects Version/s: Git Master
Fix Version/s: 2.1.3
Security Level: All

Type: Bug Priority: Blocker
Reporter: Thomas Tourlourat - Armetiz Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 2
Labels: None
Environment:

Debian 5 dotdeb
PHP 5.3
MySQL 5.0
Apache 2.2


Attachments: Text File ObjectHydrator_DDC-1410_v1.patch    

 Description   

Here an example of a simple QueryBuilder :

$queryBuilder = $entityManager->createQueryBuilder();
$queryBuilder->select ( "player, options" );
$queryBuilder->from ( "Player_Model_Entity_Player", "player");
$queryBuilder->where ("player.idPlayer = 12");
$queryBuilder->leftJoin ("player.options", "options", "WITH", "options.enabled = :enabled");
$queryBuilder->setParameter ("enabled", 1);

OptionA & OptionB & OptionC three entities.
User case :

  • OptionA.enabled = 1 & OptionB.enabled = 1 & OptionC.enabled = 1 : OK - All options are return.
  • OptionA.enabled = 1 & OptionB.enabled = 0 & OptionC.enabled = 0 : OK - only optionA is return.
  • OptionA.enabled = 1 & OptionB.enabled = 0 & OptionC.enabled = 1 : OK - only optionA & optionC is return.
  • OptionA.enabled = 0 & OptionB.enabled = 1 & OptionC.enabled = 1 : KO - no option return.
  • OptionA.enabled = 0 & OptionB.enabled = 0 & OptionC.enabled = 0 : OK - no option return.

I have test on OneToMany configuration and I have not problem. The problem only appear with ManyToMany relationships.

The problem seems to be on hydratation. The data return on SQL command seems to be correct.



 Comments   
Comment by Thomas Tourlourat - Armetiz [ 20/Oct/11 ]

I have made some other search about it.

On the queryBuilder described above, I was using getSingleResult / getResult.
When I'm using getScalarResult I can see data of every options.

Here the scalar result :

array(3) {
  [0]=>
  array(21) {
    ["player_id"]=>
    int(2)
    ["options_id"]=>
    NULL
    ["options_enabled"]=>
    NULL
  }
  [1]=>
  array(21) {
    ["player_id"]=>
    int(2)
    ["options_id"]=>
    int(2)
    ["options_enabled"]=>
    bool(true)
  }
  [2]=>
  array(21) {
    ["player_id"]=>
    int(2)
    ["options_id"]=>
    int(4)
    ["options_enabled"]=>
    bool(true)
  }
}

Do you have any clue ?

Comment by Thomas Tourlourat - Armetiz [ 20/Oct/11 ]

I think I have find the problem.

See patch.
I have test the modification, it seem to be okay.

In the 2.1.2 version, If the first related object wasn't a "nonemptyComponents", the ObjectHydrator initialized the collection by a specific way.

Comment by Thomas Tourlourat - Armetiz [ 20/Oct/11 ]

It's a patch for Doctrine/ORM/Internal/Hydration/ObjectHydrator.php version 2.1.2.

Comment by Thomas Tourlourat - Armetiz [ 20/Oct/11 ]

I have add a correction on Github : https://github.com/armetiz/doctrine2/commit/42d507632fd27a23220c38bb867b611c3caaab8e

Comment by Benjamin Eberlei [ 25/Oct/11 ]

Thanks for digging into that, I will evaluate this issue

Comment by Thomas Tourlourat - Armetiz [ 25/Oct/11 ]

No problem, It was blocking for me.
But I don't understand why this bug doesn't appear to other users. Because of that, I'm wondering if it's a real bug or a miss configuration on my app.

To be sure, the best will be to create a new test, but I'm not really familiar to create ORM test case..

Thomas.

Comment by Benjamin Eberlei [ 25/Oct/11 ]

can you post your mappings?

Comment by Thomas Tourlourat - Armetiz [ 26/Oct/11 ]

PlayerEntity :

<?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="PlayerEntity">
		<many-to-many field="options" target-entity="OptionEntity" mapped-by="players" />
	</entity>
</doctrine-mapping>
{/code}

<?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="OptionEntity" table="options">
<many-to-many field="players" target-entity="PlayerEntity" inversed-by="options">
<cascade>
<cascade-merge />
</cascade>
<join-table name="compo_option_player" />
</many-to-many>
</entity>
</doctrine-mapping>

{/code}

I have post all the mapping, but it's Doctrine compliant.
PlayerEntity extends PlayerBaseEntity, and Option is a standalone Entity.
All define an auto generated identifier.
The join table is correctly configured.

Do you need this mapping to create tests ?
To sum-up, this is a simply ManyToMany relation between an inheritance Entity & a simple Entity.

Do you need any else ?

Thomas.

Comment by Benjamin Eberlei [ 28/Oct/11 ]

Fixed.

Comment by Benjamin Eberlei [ 08/Nov/11 ]

This issue is referenced in Github Pull-Request GH-161
https://github.com/doctrine/doctrine2/pull/161

Comment by Benjamin Eberlei [ 07/Jun/12 ]

A related Github Pull-Request [GH-161] was opened
https://github.com/doctrine/dbal/pull/161

Comment by Benjamin Eberlei [ 07/Jun/12 ]

A related Github Pull-Request [GH-161] was closed
https://github.com/doctrine/dbal/pull/161

Generated at Thu Oct 23 10:19:30 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.