【问题标题】:Persist a clone坚持克隆
【发布时间】:2013-09-04 08:30:05
【问题描述】:

在这个问题Deep Cloning 我认为我的问题是由于深/浅复制。

我徒劳地测试了 clone() 和 unserialize(serialize()) 方法。

所以我尝试使用所有 setter/getter 编写自己的克隆函数,然后我意识到真正的问题是我的问题,一个持续存在的问题。

事实上,我已经成功地在另一个上下文中保存了我的实体的克隆。

我的两种情况的主要区别是,在一种情况下,我的原始对象已经由学说管理(这是我被阻止的情况),而在第二种情况下,我的原始对象只是持久化,我没有'还没有调用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:实体映射

-课程:

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

【问题讨论】:

  • 可以添加实体的映射吗?

标签: php symfony doctrine-orm persist


【解决方案1】:

事情是ManyToMany相关实体没有被克隆,试试这个:

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;

    $teachers = $course->getTeachers();
    $duplicate->setTeachers($teachers);

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

这样,您将在两个实体之间保持新的关系和新的连接表

编辑: 也许它是一个级联问题,是什么给了你这个? :

$teachers = $course->getTeachers();

foreach ($teachers as $teacher) { 
    $teacher->addCourse($duplicate); 
    $em->persist($teacher); 
}

【讨论】:

  • 感谢您的回答。实际上,我的老师是由克隆人设置的。如果我在克隆后立即 var_dump() 我的副本,我可以看到它们。只是没有持久化...
  • 其他:您的架构是否正确? (命令php app/console doctrine:schema:validate
  • 它没有任何改变...我的实体映射有一些失败,但与课程或用户没有任何关系。
  • 那么,如果我在 var_dump() 时可以看到我的老师,为什么他们不坚持?有什么想法吗?
  • 您是否尝试在 foreach 循环中调用 $duplicate->addTeacher($teacher) ?
猜你喜欢
  • 2019-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-19
  • 2017-12-22
相关资源
最近更新 更多