Глубокое клонирование объекта: Clone vs Serialize

У меня есть эта функция duplicateCourseAction, целью которой является … дублировать объект курса

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"); } 

Согласно документам, ключевое слово «клонировать» делает копию поверхности (то есть эталонную копию). Это явно не то, что я хочу, потому что мой объект курса содержит много отношений с другими объектами, я бы предпочел, чтобы значения копировались.

Я обнаружил неэтериализованный (сериализующий (объект)) трюк:

 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"); } 

Но у меня есть эта ошибка с Доктриной:

Примечание. Неопределенный индекс: 000000003ed2e9ea00000000ee270fde в /home/mart_q/Diderot/ent/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php строке 2776

Solutions Collecting From Web of "Глубокое клонирование объекта: Clone vs Serialize"

Вы можете управлять тем, что точно клонируется путем переопределения метода __clone() в вашей сущности Course . Вы можете установить id в null и клонировать объекты, на которые ссылаются, если вам нужна глубокая копия.

Сериализация / unserialization чувствует себя как взломать, поэтому я рекомендую не использовать его.

Трюк здесь заключается в том, что вы должны отключить дублированный идентификатор объекта. В противном случае нарушается логика доктрины. У Доктрины есть некоторые известные ограничения . Также проверьте этот вопрос , это очень похоже.