0

I have some entities with abstract class : EntityDated wich mean that the entity contain 4 commons fields : created, updated, created_by and updated_by. I want update the 4 data when I create entity and update 'updated' and 'updated_by' when I update the entity.

I made a service calling my listener :

public function preUpdate(PreUpdateEventArgs $eventArgs)
    {
        $token = $this->container->get('security.context')->getToken();
        $entity = $eventArgs->getEntity();
        $em = $eventArgs->getEntityManager();
        $uow = $em->getUnitOfWork();

        if (is_subclass_of($entity, 'Kiwi\Bundle\TrainingBundle\Entity\EntityDated')) {
            $entity->setUpdated(new \Datetime()); 
            $entity->setUpdatedBy($token->getUser()->getUsername()); 

            $meta = $em->getClassMetadata(get_class($entity));
            $uow->recomputeSingleEntityChangeSet($meta, $entity);
        }
    }

This works perfectly with simple entities with no entities linked BUT as soon as i try to add an entity linked (for instance I add one entity "Response" to the array of $responses of my entity "Question") I have the following error :

Notice: Undefined index: 0000000060e7f05700000000e7f2194b in C:\wamp\www\kiwi\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php line 1359

The problem is that the linked entity is persisted not by a direct call of $em->persist() but by the behaviour : cascade="persist" and as the Doc says about recomputeSingleEntityChangeSet() :

The passed entity must be a managed entity. If the entity already has a change set because this method is invoked during a commit cycle then the change sets are added. whereby changes detected in this method prevail.

So obviously the problem here is that my entity linked is not managed. How could I add it to the UnitOfWork or something in order to manage it ?

KmeCnin
  • 507
  • 3
  • 16
  • 1
    Did you try using [`preFlush` instead of `preUpdate`](http://stackoverflow.com/a/19111402/1188035)? – sjagr Oct 08 '14 at 15:55

1 Answers1

0

In order to perform both Inserts and Updates I had to change two points :

  • Use onFlush(), not preFlush()
  • Add recomputeSingleEntityChangeSet() after each change

The new code :

public function onFlush(OnFlushEventArgs $eventArgs)
{

    $token = $this->container->get('security.context')->getToken();
    $em = $eventArgs->getEntityManager();
    $uow = $em->getUnitOfWork();

    // Inserts
    foreach ($uow->getScheduledEntityInsertions() as $entity) {
        if (is_subclass_of($entity, 'Kiwi\Bundle\TrainingBundle\Entity\EntityDated')) {

            $entity->setCreated(new \Datetime()); 
            $entity->setCreatedBy($token->getUser()->getUsername());
            $entity->setUpdated(new \Datetime()); 
            $entity->setUpdatedBy($token->getUser()->getUsername()); 

            $meta = $em->getClassMetadata(get_class($entity));
            $uow->recomputeSingleEntityChangeSet($meta, $entity);

        }
    }

    // Updates
    foreach ($uow->getScheduledEntityUpdates() as $entity) {
        if (is_subclass_of($entity, 'Kiwi\Bundle\TrainingBundle\Entity\EntityDated')) {

            $entity->setUpdated(new \Datetime()); 
            $entity->setUpdatedBy($token->getUser()->getUsername());

            $meta = $em->getClassMetadata(get_class($entity));
            $uow->recomputeSingleEntityChangeSet($meta, $entity); 

        }                
    }

}
KmeCnin
  • 507
  • 3
  • 16