1

この問題のDeep Cloningでは、私の問題はディープ/シャロー コピーが原因であると考えました。

clone() および unserialize(serialize()) メソッドを無駄にテストしました。

そのため、すべてのセッター/ゲッターを使用して独自のクローン関数を作成しようとしましたが、実際に私の問題、永続的な問題であることに気付きました。

実際には、別のコンテキストでエンティティのクローンを永続化することにすでに成功しています。

私の 2 つの状況の主な違いは、1 つのケースでは元のオブジェクトがすでにドクトリンによって管理されていることです (これは私がブロックされている場合です)。まだ flush() と呼ばれています (そして、正常に動作しています)。

したがって、これは永続化が多対多の関係を永続化しない場合の状況です:

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->setId(null);
    $duplicate->setDate(new \DateTime($parameters['date']));
    $em->persist($duplicate);
    $em->flush();
    return new Response("200");
}

そして、これはそれが魅力のように機能する状況です

        $em->persist($obj);
        while ($new_date < $up_to) {
            if ($this->isAvailable($holidays, $new_date)) {
                $new_course = clone $obj;
                $new_course->setDate($new_date);
                $new_course->setUuid($uuid);
                $new_date = clone $new_date;
                $em->persist($new_course);
            }
            $new_date->modify($modifier);
        }
        $em->flush();

なぜ1つの状況でしか機能しないのですか? ほとんど同じものがあります...

編集 1: エンティティ マッピング

-コース :

class Course {

/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

/**
 * @ORM\Column(type="string", length=50, unique=true, nullable=true)
 */
protected $name;

/**
* @ORM\JoinColumn(onDelete="CASCADE")
* @ORM\ManyToOne(targetEntity="Ent\HomeBundle\Entity\Campus", inversedBy="courses")
* @Assert\NotBlank
**/
protected $campus;

/**
* @ORM\JoinColumn(onDelete="CASCADE")
* @ORM\ManyToOne(targetEntity="Ent\HomeBundle\Entity\Room", inversedBy="courses")
* @Assert\NotBlank
**/
protected $room;

/**
 * @ORM\ManyToMany(targetEntity="Ent\UserBundle\Entity\User", inversedBy="courses", cascade={"persist"})
 * @ORM\JoinTable(name="course_teacher",
 *  joinColumns={@ORM\JoinColumn(name="course_id", referencedColumnName="id", onDelete="CASCADE")},
 *  inverseJoinColumns={@ORM\JoinColumn(name="teacher_id", referencedColumnName="id", onDelete="CASCADE")}
 * )
 * @Assert\NotBlank
 */
private $teachers;

/**
* @ORM\JoinColumn(onDelete="CASCADE")
* @ORM\ManyToOne(targetEntity="Matter", inversedBy="courses")
* @Assert\NotBlank
**/
protected $matter;

/**
* @ORM\JoinColumn(onDelete="CASCADE")
* @ORM\ManyToOne(targetEntity="\Ent\UserBundle\Entity\Grade", inversedBy="courses")
* @Assert\NotBlank
**/
protected $grade;

/**
* @ORM\Column(type="datetime")
* @Assert\NotBlank
**/
protected $date;

/**
* @ORM\Column(type="time")
* @Assert\NotBlank
**/
protected $duration;

/**
 * @ORM\Column(type="string", length=30, nullable=true)
 */
protected $uuid;

/**
 * @ORM\ManyToMany(targetEntity="Ent\TimeBundle\Entity\Course", mappedBy="courses")
 * @Exclude
*/
protected $alerts;

public function __toString() {
    if (empty($this->getName())) {
        $string = $this->getMatter().' - '.$this->getRoom().' - ';
        foreach ($this->getTeachers() as $count => $teacher) {
            $string = $string . $teacher;
            if ($count < count($this->getTeachers()) - 1) {
                $string = $string . ', ';
            }
        }
        return $string;
    } else {
        return $this->getName().' - '.$this->getRoom();
    }
}
/**
 * Constructor
 */
public function __construct() {
    $this->teachers = new ArrayCollection();
    $this->alerts = new ArrayCollection();
}

public function __clone() {
    // $this->id = null;
    // $this->teachers = clone $this->teachers;
}
}

-ユーザー (教師) :

class User implements UserInterface, \Serializable {
/**
 * @ORM\Column(type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

/**
 * @ORM\Column(type="string", length=30)
 * @Assert\NotBlank
 */
protected $firstName;

/**
 * @ORM\Column(type="string", length=30)
 * @Assert\NotBlank
 */
protected $lastName;

/**
 * @ORM\Column(type="string", length=70, unique=true)
 * @Assert\NotBlank
 */
protected $username;

/**
 * @Gedmo\Slug(fields={"username"}, updatable=false)
 * @ORM\Column(length=50, unique=true)
 */
protected $slug;

/**
 * @ORM\Column(type="string", length=32)
 * @Exclude
 */
protected $salt;

/**
 * @ORM\Column(type="string", length=40)
 * @Exclude
 */
protected $password;

/**
 * @ORM\Column(type="string", length=255, nullable=true)
 */
protected $picture_path;

/**
 * @Assert\File(maxSize="10M", mimeTypesMessage="Please upload a valid Image")
 */
protected $picture;

/**
 * @ORM\Column(type="string", length=60, unique=true)
 * @Exclude
 * @Assert\NotBlank
 */
protected $email;

/**
 * @ORM\Column(name="is_active", type="boolean")
 */
protected $isActive;

/**
 * @ORM\ManyToOne(targetEntity="Group", inversedBy="users")
 * @ORM\JoinColumn(name="role_group", referencedColumnName="role", onDelete="CASCADE")
 */
protected $group;

/**
* @ORM\ManyToMany(targetEntity="Ent\HomeBundle\Entity\Campus", inversedBy="users")
* @Exclude
**/
protected $campuses;

/**
 * @ORM\OneToMany(targetEntity="\Ent\NewsBundle\Entity\News", mappedBy="user")
 * @Exclude
 */
protected $news;

/**
 * @ORM\ManyToMany(targetEntity="\Ent\TimeBundle\Entity\Matter", inversedBy="teachers", cascade={"persist"})
 * @ORM\JoinTable(name="user_matter",
 *  joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE")},
 *  inverseJoinColumns={@ORM\JoinColumn(name="matter_id", referencedColumnName="id", onDelete="CASCADE")}
 * )
 */
protected $matters;

/**
* @ORM\ManyToMany(targetEntity="Ent\UserBundle\Entity\Grade")
* @Assert\NotBlank
* @Exclude
**/
protected $grades;

/**
* @ORM\ManyToMany(targetEntity="Ent\TimeBundle\Entity\Course", mappedBy="teachers")
* @Exclude
**/
protected $courses;

/**
* @ORM\OneToMany(targetEntity="\Ent\TimeBundle\Entity\Alert", mappedBy="teacher")
* @Exclude
**/
protected $alerts;

protected $temp;

public function __construct() {
    $this->isActive = true;
    $this->salt = md5(uniqid(null, true));
}

public function __toString() {
    return $this->getFullName();
}
}

編集2:解決策

Paul Andrieuxのおかげで、これはオブジェクトのクローンを作成するために作成した関数です。

public function course_deep_clone($course) {
    $em = $this->getDoctrine()->getManager();
    $clone = clone $course;

    $clone->setTeachers(array());
    $teachers = $course->getTeachers();
    foreach ($teachers as $teacher) {
        $clone->addTeacher($teacher);
    }

    return $clone;
}
4

1 に答える 1