On update don't update an entity replace it

74 views Asked by At

I have a Branch entity that has an Address entity, one address can be link to many other types of entities, what I want to do is when I edit the Address in the Branch entity instead of editing the address with the new data I want to create a new Address entity and attach it to the Branch, what is happening right now is that its editing the address, the problem with this is that I have other entities linked to that address.

This is my form:

class MBBranchType extends AbstractType{

   protected $em;

   function __construct(EntityManager $em){
       $this->em = $em;
   }

   /**
    * @param FormBuilderInterface $builder
    * @param array $options
    */
   public function buildForm(FormBuilderInterface $builder, array $options)
   {
       $builder
        ->add('branchName')
        ->add('branchCode')
        ->add('destiny', 'entity', array(
            'class' => 'ATRBundle:Destiny',
            'empty_value' => '-- Seleccione --',
            'mapped' => true,
            'query_builder' => function(EntityRepository $er){
                    return $er->createQueryBuilder('d')
                        ->orderBy('d.destinyDesc', 'ASC');
        }))
        ->add('startOperation', 'text')
        ->add('stopOperation', 'text', array('required' => ''))
        ->add('authorizationL1', 'checkbox', array('required' => ''))
        ->add('authorizationL2', 'checkbox', array('required' => ''))
        ->add('authorizationL3', 'checkbox', array('required' => ''))
        ->add('address', new AddressType($this->em, new Address()), array('required' => ''))
        ->add('active', 'checkbox', array('required' => ''));

    $builder->get('startOperation')->addModelTransformer(new StringToDateTransformer());
    $builder->get('stopOperation')->addModelTransformer(new StringToDateTransformer());

   }

   /**
    * @param OptionsResolverInterface $resolver
    */
   public function setDefaultOptions(OptionsResolverInterface $resolver)
   {
       $resolver->setDefaults(array(
           'data_class' => 'MB2\ATRBundle\Entity\MBBranch'
       ));
   }

   /**
    * @return string
   */
   public function getName()
   {
      return 'mb2_atr_mb_branch';
   }
}

This is my Action

public function editMBBranchAction()
{
    $id = $this->request->query->get('id');
    $entity = $this->em->getRepository('ATRBundle:MBBranch')->find($id);
    $form = $this->createForm(new MBBranchType($this->getDoctrine()->getManager()), $entity);

    $form->handleRequest($this->request);

    if ($form->isValid()) {

        if($entity instanceof MBBranch){

            $addressEntity = $this->em->getRepository('ATRBundle:Address')->findOneBy(

                array('street'=>(string)$entity->getAddress()->getStreet()
                        , 'exteriorNum' => $entity->getAddress()->getExteriorNum();
                        , 'interiorNum' => $entity->getAddress()->getInteriorNum();
                        , 'settlment' => $entity->getAddress()->getSettlment()
                )
            );

            if($addressEntity instanceof \MB2\ATRBundle\Entity\Address){
                $entity->setAddress($addressEntity);
            }else{

                $otherAddress = new Address();

                $otherAddress->setStreet($entity->getAddress()->getStreet());
                $otherAddress->setExteriorNum($entity->getAddress()->getExteriorNum());
                $otherAddress->setInteriorNum($entity->getAddress()->getInteriorNum());
                $otherAddress->setSettlment($entity->getAddress()->getSettlment());

                $entity->setAddress($otherAddress);
            }

            $this->em->flush();
        }

        return $this->redirect($this->generateUrl('admin', array('action' => 'list', 'entity' => $this->entity['name'])));
    }

    return $this->render($this->entity['templates']['edit'], array(
        'form'          => $form->createView(),
        'entity'        => $entity,
    ));
}

As you can see it checks if the new Address entity exist, if it does exist it sets it on the $entity->setAddress($addressEntity);, If it does not exist it created a new Address() and sets the values, This does work, it created a new Address and saves it on the table, but for some reason it also updateing the old Address entity.

1

There are 1 answers

0
gastoncs On

I found the solution

I added a $this->em->detach($entity->getAddress()); before attaching a new Address, please see example.

public function editMBBranchAction()
{
    $id = $this->request->query->get('id');
    $entity = $this->em->getRepository('ATRBundle:MBBranch')->find($id);
    $form = $this->createForm(new MBBranchType($this->getDoctrine()->getManager()), $entity);

    $form->handleRequest($this->request);

    if ($form->isValid()) {

        if($entity instanceof MBBranch){

            $this->em->detach($entity->getAddress());

            $addressEntity = $this->em->getRepository('ATRBundle:Address')->findOneBy(

                array('street'=>(string)$entity->getAddress()->getStreet()
                        , 'exteriorNum' => $entity->getAddress()->getExteriorNum();
                        , 'interiorNum' => $entity->getAddress()->getInteriorNum();
                        , 'settlment' => $entity->getAddress()->getSettlment()
                )
            );

            if($addressEntity instanceof \MB2\ATRBundle\Entity\Address){
                $entity->setAddress($addressEntity);
            }else{

                $otherAddress = new Address();

                $otherAddress->setStreet($entity->getAddress()->getStreet());
                $otherAddress->setExteriorNum($entity->getAddress()->getExteriorNum());
                $otherAddress->setInteriorNum($entity->getAddress()->getInteriorNum());
                $otherAddress->setSettlment($entity->getAddress()->getSettlment());

                $entity->setAddress($otherAddress);
            }

            $this->em->flush();
        }

        return $this->redirect($this->generateUrl('admin', array('action' => 'list', 'entity' => $this->entity['name'])));
    }

    return $this->render($this->entity['templates']['edit'], array(
        'form'          => $form->createView(),
        'entity'        => $entity,
    ));
}