【问题标题】:Symfony2 many-to-many does not update inverse sideSymfony2 多对多不更新反面
【发布时间】:2015-10-09 10:18:10
【问题描述】:

我有实体:学生和学习组

学习小组一切正常。我可以选择 Student 属于 Study Groups 的列表,Doctrine 创建关联。

但是,当我想从另一边做同样的事情(为学生选择学习小组)时,什么也没有发生。

这是我的 YAML 文件配置的重要部分

StudyGroups.orm.yml

manyToMany:
    students:
        targetEntity: Students
        inversedBy: studyGroups
        cascade: ["persist"]
        joinTable:
            name: students_study_groups
            joinColumns:
                study_groups:
                    referencedColumnName: id
            inverseJoinColumns:
                students:
                    referencedColumnName: id

Students.orm.yml

manyToMany:
    studyGroups:
        targetEntity: StudyGroups
        mappedBy: students
        cascade: ["persist"]
lifecycleCallbacks: {  }

我也在StudyGroups.php实体文件中尝试了如下修改

public function addStudent(\AppBundle\Entity\Students $students) {
    $students->addStudyGroup($this); // ADDED THIS LINE
    $this->students[] = $students;
    return $this;
}

Students.php 实体文件中相同

public function addStudyGroup(\AppBundle\Entity\StudyGroups $studyGroups) {
    $studyGroups->addStudent($this); // ADDED THIS LINE
    $this->studyGroups[] = $studyGroups;
    return $this;
}

我发现这个问题的有趣之处在于,如果我在 StudyGroups.orm.yml 和 Student.orm.yml 中切换 Inverse 和 Owning 端,问题也会切换。

我知道这里提到了这一点:http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/unitofwork-associations.html

11.2。重要概念

仅对关联反面所做的更改将被忽略。确保更新双向关联的双方(或至少从 Doctrine 的角度来看拥有方)

这是我的问题。我对反面的更改被忽略。我怎样才能解决这个问题 ?我尝试了其他用户提到的所有这些东西,但仍然无法正常工作。提前致谢。

更新 1

这是我编辑学生的方法。请注意,如果我切换反向和拥有方(在 YAML 文件配置中),学习组编辑将起作用,而学生编辑将不起作用。 (不工作,我的意思是它不会在两者之间建立关联)

public function editStudentAction(Request $request, $student) {

    /* DATABASE SERVICE */
    $this->db_helper = $this->get('db.helper');

    /* DOCTRINE */
    $em = $this->getDoctrine()->getManager();
    $student = $em->getRepository('AppBundle:Students')->find($student);

    /* INVALID ID */
    if (count($student) == 0) {
        /* INVALID ID */
        $request->getSession()->getFlashBag()->add(
                'error', 'Invalid ID!'
        );
        return $this->redirect($this->generateUrl('index'));
    }

    /* GET STUDENT FORM */
    $form = $this->newStudentForm($student, "edit");

    /* HANDLE FORM SUBMISSION */
    $form->handleRequest($request);
    if ($form->isValid()) {

        /* CHECK IF STUDENT ONLY WANT TO ENROLL 2 STUDY GROUPS */
        if (count($student->getStudyGroups()) > 2) {
            $request->getSession()->getFlashBag()->add(
                    'error', 'Students may only enroll 2 study groups at the same time!'
            );
        } else {
            try {

                /* SAVE TO DATABASE */
                $em->persist($student);
                $em->flush();

                /* REDIRECT TO MAIN PAGE */
                return $this->redirect($this->generateUrl('index'));
            } catch (\Doctrine\DBAL\DBALException $e) {

                /* HANDLE DUPLICATE KEY ISSUE */
                if ($e->getPrevious()->getCode() === '23000') {
                    $request->getSession()->getFlashBag()->add(
                            'error', 'User already exists!'
                    );
                } else
                    throw $e;
            }
        }
    }

    return $this->render('default/new.html.twig', array(
                'form' => $form->createView(),
                'object' => "student"
    ));
}

【问题讨论】:

  • 你能告诉我们你的控制器吗?我有一种感觉,我可以看到发生了什么,但需要看到你的控制器才能确定。
  • 我添加了控制器部分。

标签: php symfony orm doctrine-orm doctrine


【解决方案1】:

我很惊讶这对双方都有效,因为看起来你有一个潜在的无限循环发生。

addStudent() 调用 addStudyGroup() 调用 addStudent() 调用 addStudyGroup() 调用 addStudent()............删除那两个“添加这条线”,这需要发生在你的控制器中。

这是您控制器中的更新。首先,您需要在创建表单之前记住该学生的现有学习小组列表:

    /* GET ORIGNAL COLLECTIONS */
    $originalGroups = new ArrayCollection(); // requires: use Doctrine\Common\Collections\ArrayCollection;
    foreach ($student->getStudyGroups() as $group) {
        $originalGroups->add($group);
    }

    /* GET STUDENT FORM */

现在您需要从新集合中删除所有已删除的研究组,

    /* MANY TO MANY */
    foreach ($originalGroups as $group) {
        if (!$student->getStudyGroups()->contains($group)) {
            $student->removeStudyGroup($group);
            $group->removeStudent($student);
            $em->remove($group);
        } else {
            $group->addStudent($student);
            $em->persist($group);
        }
    }

    /* SAVE TO DATABASE */
    $em->persist($student);

【讨论】:

  • 所以情况如下。我想编辑一个有 2 个学习小组的学生。我将他从其中一个学习组中删除,我收到此错误:使用参数 [1, 98] 执行“INSERT INTO students_study_groups (study_groups,students) VALUES (?, ?)”时发生异常:SQLSTATE[23000]: Integrity违反约束:1062 键 'PRIMARY' 的重复条目 '98-1'
  • 您是否从您的实体中删除了“// ADDED THIS LINE”行?由于我提到的循环,将发生该错误。这一行“$group->addStudent($student);”也可能不需要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-05
  • 2015-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多