2

嗨,我有一个将人员添加到组的操作。

为了增加可用性,它的表格删除了已经在组中的人。

我的控制器操作如下所示:

public function addAction(UserGroup $userGroup)
{
      $tempGroup = new UserGroup();
      foreach ($userGroup->getUsers() as $user) {
           $tempGroup->addUser($user);
      }
      $form = $this->container->get('form.factory')->create(new UserGroupQuickType(), $tempGroup);

      $request = $this->container->get('request');

      if ('POST' === $request->getMethod()) {
           $form->submit($request);

           if ($form->isValid()) {
               $group = $form->getData();

               /** @var $myUserManager UserManager */
               $myUserManager = $this->container->get('strego_user.user_manager');
               /** @var $em EntityManager */
               $em = $this->container->get('em');

               foreach ($group->getUsers() as $toInvite) {
              $userGroup->addUser($toInvite);
               }
           $em->persist($userGroup);
               $em->flush($userGroup);

           }
      }

      return array(
             'form' => $form->createView(),
             'userGroup' => $userGroup
      );
}

此代码引发异常:

A new entity was found through the relationship 'Strego\UserBundle\Entity\UserGroup#users' 
that was not configured to cascade persist operations for entity: Degi. 
To solve this issue: Either explicitly call EntityManager#persist() on 
this unknown entity or configure cascade persist this 
association in the mapping for example @ManyToOne(..,cascade={"persist"}).

新发现的与之前的关系已经存在。这意味着用户“Degi”已经在组中并且不是新实体。

如果我省略持久性,我可以避免这个错误,但我会得到一个异常:Entity has to be managed or scheduled for removal for single computation.

这是由于我的“用户组”实体的实体状态一直为 3(= 分离)

我对与我的用户组具有 1 对 1 关系的实体使用了相同的逻辑(使用临时组等),从那里我可以轻松地将人员添加到组中。但不是这个动作,它在逻辑上做完全相同的事情。

更新: 我之前的更新方向错误。但相比之下,工作的(几乎)相同的控制器:

public function addAction(BetRound $betRound)
    {

        $userGroup = new UserGroup();
        foreach ($betRound->getUsers() as $user) {
            $userGroup->addUser($user);
        }
        $form = $this->createForm(new UserGroupQuickType(), $userGroup);

        $request = $this->getRequest();

        if ('POST' === $request->getMethod()) {

            $form->submit($request);
            if ($form->isValid()) {
                /** @var $betRoundManager BetRoundManager */
                $betRoundManager = $this->container->get('strego_tipp.betround_manager');
                /** @var $myUserManager UserManager */
                $myUserManager = $this->container->get('strego_user.user_manager');

                $group = $form->getData();

                foreach ($group->getUsers() as $toInvite) {
                    if (!$betRound->getUserGroup()->hasUser($toInvite)) {
                        $betRound->getUserGroup()->addUser($toInvite);
                    }
                }
                $this->getDoctrine()->getManager()->flush();
                return $this->redirect($this->generateUrl('betround_show', array('id' => $betRound->getId())));
            }
        }

        return array(
            'form' => $form->createView(),
            'betRound' => $betRound
        );
    }
4

3 回答 3

0

发生这种情况是因为它已经是一个$userGroup已经存在并且$toInvite是一个新实体的实体,并且您正在尝试刷新$userGroup。要使此代码正常工作,您需要cascade={"persist"}在实体文件中指定(注释或 yaml,无论您喜欢哪个)。

其他解决方案是做相反的事情并坚持$toInvite

foreach ($group->getUsers() as $toInvite) {
    $toInvite->setUserGroup($userGroup);
    $em->persist($toInvite);
}
$em->flush();

我认为第一个选项会是更好的选择

于 2013-10-07T07:05:58.110 回答
0

经过几次尝试,我发现这个问题实际上是 2 个问题: 1. 我有一个侦听器,它更新了一些行,即使没有必要。2. paramconverter 以某种方式分离了进来的实体。这意味着我的 UserGroup 和我在其中的所有用户都被分离了。一旦将它们再次添加到用户组,这些实体对于 EM 来说似乎是“新的”。因此,我需要合并所有用户并修复更新“createdBy”的侦听器,否则也需要合并。

于 2013-10-14T08:10:13.970 回答
0

这是预期的行为,因为您与,不是真正的新实体而是非托管对象有关系。

在迭代时,您可以尝试 merging $toInvite。不用担心,如果您通过表单获取的对象设置了适当的标识符 ( @Id) 值,它们只会从数据库中重新加载,而不是标记为插入。另一方面,新添加的对象将被标记。

因此,在尝试任何事情之前,请确保每个 old$toInvite都有一个 ID 集。

foreach ($group->getUsers() as $toInvite) {
    $em->merge($toInvite);
    $userGroup->addUser($toInvite);
}
// safe to do now, all of the added users are either reloaded or marked for insertion
$em->perist($usetGroup); 
$em->flush($userGroup);

希望这可以帮助。

于 2013-10-05T21:29:11.210 回答