[DDC-2317] [UnitOfWork] Entity in identityMap but not present in entityIdentifiers Created: 24/Feb/13  Updated: 26/Feb/13  Resolved: 26/Feb/13

Status: Closed
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.3.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Rémi Piotaix Assignee: Marco Pivetta
Resolution: Invalid Votes: 0
Labels: orm, unitofwork
Environment:

php 5.4.11, MySQL 5.5, ubuntu 12.10


Attachments: File Buff.php     File Competence.php     File CompetenceAction.php     File CompetenceActionBuff.php     File CompetenceActionBuffType.php    

 Description   

I'm using symfony 2.1.8 and sonata/admin-bundle
I have a quite complex entity mapping.

  • A Competence has many CompetenceAction (superclass)
  • CompetenceActionBuff is a subclass of CompetenceAction and has exactly one buff (selectable in the form by an 'entity' field).

When i want to edit a Competence, i have the following error message about the Buff entity linked to the CompetenceActionBuff:
"Entities passed to the choice field must be managed. [...]"
The exception is raised in Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php at line 412

I've added some debug code in the EntityManager::contains() method and it shows that my entity is in the entityMap but his oid is not in the keys of entityIdentifiers making the call to UnitOfWork::isInIdentityMap() return false at line 1505.

When submitting the form, there is no problems. All the entities are correctly created in the database. The exception is thrown only when i want to edit the Competence object. Saying that the Buff object is not managed when it was first loaded from the database... strange, no?

Finally, i tried to comment the test

if (!$this->em->contains($entity)))

in EntityChoiceList::getIdentifierValues() and everything seemed to work properly.



 Comments   
Comment by Marco Pivetta [ 24/Feb/13 ]

Can you please reproduce this in an insulated environment (without symfony forms involved)?

Comment by Rémi Piotaix [ 24/Feb/13 ]

By doing this, all work properly, the exception is not thrown:

$competence = $this->getRepo(\Sistearth\JeuBundle\Entity\Competence\Competence::REPO)->find(1);
$buff = $competence->getActions()[0]->getBuff();
      
$em = $this->getDoctrine()->getEntityManager();
        
if(!$em->contains($buff))
    throw new \Exception("Not in EntityManager");

but if i add this after:

$form = $this->createForm(new \Sistearth\JeuBundle\Form\Competence\CompetenceType(), $competence);

then, the exception "Entities passed to the choice field must be managed. Maybe persist them in the entity manager?" is back.

I'll try to do some others tests...

Comment by Marco Pivetta [ 24/Feb/13 ]

Rémi Piotaix the problem is exactly the last bit Doctrine has no forms, so you will have to create a small script that reproduces the problem without symfony, starting from:

php composer.phar require doctrine/orm:dev-master@dev
Comment by Rémi Piotaix [ 24/Feb/13 ]

Bug found!

In the form type CompetenceActionBuffType, i marked the field buff with

array('by_reference"=>false)

. If by_reference is set to false, the modelData is cloned (here the Buff proxy) at line 349 in Form.php.
And, by cloning the object, the spl_object_hash of the clone is different from the original one's.

Is this a symfony Form component bug or a doctrine one?

Comment by Marco Pivetta [ 26/Feb/13 ]

Rémi Piotaix this is a problem of symfony forms, please report it on the symfony issue tracker (check if there's a similar open issue first) at https://github.com/symfony/symfony/issues/

Generated at Sat Sep 20 22:14:00 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.