1

I have this function duplicateCourseAction whose goal is to ... duplicate a Course object

public function duplicateCourseAction(Request $request) {
    if ($this->getRequest()->isXmlHttpRequest() == false) {
        return new Response("Bad request", 405);
    }

    $em = $this->getDoctrine()->getManager();
    $parameters = $request->request->all();
    $course = $em->getRepository('EntTimeBundle:Course')->findOneById($parameters['id']);
    $duplicate = clone $course;
    $duplicate->setDate(new \DateTime($parameters['date']));
    $em->persist($duplicate);
    $em->flush();
    return new Response("200");
}

According to documentations, "clone" keyword make a surface copy (ie. a reference copy). This is clearly not what I want because my Course entity contains many relations to others entities, I would rather want a values copy.

I discovered the unserialize(serialize(object)) trick :

public function duplicateCourseAction(Request $request) {
    if ($this->getRequest()->isXmlHttpRequest() == false) {
        return new Response("Bad request", 405);
    }

    $em = $this->getDoctrine()->getManager();
    $parameters = $request->request->all();
    $course = $em->getRepository('EntTimeBundle:Course')->findOneById($parameters['id']);
    $duplicate = unserialize(serialize($course));
    $duplicate->setDate(new \DateTime($parameters['date']));
    $em->persist($duplicate);
    $em->flush();
    return new Response("200");
}

But I have this error with Doctrine :

Notice: Undefined index: 000000003ed2e9ea00000000ee270fde in /home/mart_q/Diderot/ent/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php line 2776

Elnur Abdurrakhimov
  • 44,533
  • 10
  • 148
  • 133

2 Answers2

0

Trick here is that you must unset duplicate entity id. Otherwise breaks the logic of the doctrine. Doctrine has some known limitations. Also check this question, its very similar.

Community
  • 1
  • 1
Alexey B.
  • 11,965
  • 2
  • 49
  • 73
0

You can control what exactly gets cloned by overriding the __clone() method in your Course entity. You can set id to null and clone referenced objects if you need a deep copy.

The serialization/unserialization feels like a hack, so I recommend against using it.

Elnur Abdurrakhimov
  • 44,533
  • 10
  • 148
  • 133
  • I'm doing this : `public function __clone() { $this->id = null; $this->teachers = clone $this->teachers; }` But I have : FatalErrorException: Error: __clone method called on non-object. Is this beacause teachers is an ArrayCollection() ? –  Sep 03 '13 at 19:20
  • It's hard to tell from what you've provided. Try and fail and try again, debug, comment out different parts of code to see what's failing. I've put you on the right path, but you need to figure out the details yourself. – Elnur Abdurrakhimov Sep 03 '13 at 19:34
  • I already testes __clone() before, but if you say me this is the right way, i'll try to figure out what is going wrong by myself. Thanks :) –  Sep 03 '13 at 19:46