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.

これは、私の "usergroup" エンティティのエンティティ ステータスが常に 3 (= detached) であることが原因です。

ユーザーグループと 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"}には、エンティティ ファイルで指定する必要があります (Annotations または yaml のいずれか好きな方)。

他の解決策は、逆のことをして永続化することです$toInvite

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

最初のオプションがより良い選択になると思います

于 2013-10-07T07:05:58.110 に答える
0

何度か試行した結果、この問題は実際には 2 つの問題であることがわかりました。2. paramconverter は何らかの形で入ってくるエンティティを切り離します。これは、私の UserGroup とその中のすべてのユーザーが切り離されることを意味します。ユーザーグループに再び追加されるとすぐに、それらのエンティティは EM にとって「新しい」ように見えます。したがって、すべてのユーザーをマージし、「createdBy」を更新するリスナーを修正する必要がありました。そうでなければ、これもマージする必要がありました。

于 2013-10-14T08:10:13.970 に答える
0

実際には新しいエンティティではなく、管理されていないオブジェクトと関係があるため、これは予想される動作です。

繰り返しながら、マージを試すことができます$toInvite。フォーム経由で取得したオブジェクトに適切な識別子 ( @Id) の値が設定されている場合、オブジェクトは挿入用にマークされるのではなく、データベースから再ロードされるだけです。一方、新しく追加されたオブジェクトはマークされます。

したがって、何かを試す前に、それぞれに$toInviteID が設定されていることを確認してください。

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 に答える