Reputation: 2191
I am having a ControllerAction that allows a User to join a Usergroup.
The UserGroup is fetched via Paramconverter and the user is always the current logged in user.
/*
* @ParamConverter("code", class="StregoUserBundle:UserGroup", options={"mapping": {"code": "code"}})
* @param \Strego\UserBundle\Entity\UserGroup $code UserGroup Code
*/
public function joinGroupAction($code){
$userManager = $this->get('strego_user.user_manager');
$userManager->joinGroup($code, $this->getUser());
return new Message('Erfolgreich der Gruppe beigetreten', 'success');
}
$this->getUser is using Symfony2 Base Controller, which is basically getting the user from the securityContext.
My joinGroup looks like this:
public function joinGroup(UserGroup $userGroup, User $user){
if (!$userGroup->getUsers()->contains($user)) {
$userGroup->addUser($user);
$this->em->merge($user);
$this->em->persist($userGroup);
$this->dispatcher->dispatch(
UserEvents::USER_USERGROUP_JOIN,
new UserGroupUserEvent($userGroup, $user)
);
$this->em->flush();
}
}
As you can see, I already try to merge the user but I still get the following error Message: Uncaught PHP Exception Doctrine\ORM\ORMInvalidArgumentException: "A new entity was found through the relationship 'Strego\UserBundle\Entity\UserGroup#users' that was not configured to cascade persist operations for entity: mof. 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"})."
I have already researched a lot about this issue, but all possible causes (not merging, em clear, using multiple em) do not apply to this case.
My Configuration looks like this:
class UserGroup extends BaseGroup {
/**
* @var Collection users
* @ORM\ManyToMany(targetEntity="User", inversedBy="userGroups" )
* @ORM\JoinTable(name="user_user_usergroup")
* @Serialize\Expose()
* @Serialize\MaxDepth(2)
* @Serialize\Groups({"usergroup"})
*
*/
protected $users;
}
class User extends BaseUser {
/**
* @var Collection userGroups
*
* @ORM\ManyToMany(targetEntity="UserGroup", mappedBy="users")
* @ORM\JoinTable(name="user_user_usergroup",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}
* )
*/
private $userGroups;
}
Update I tried to change the persisting around, since the "User" is defined as Owning side:
public function joinGroup(UserGroup $userGroup, User $user){
if (!$userGroup->getUsers()->contains($user)) {
$user->addUserGroup($userGroup);
$this->em->persist($user);
$this->dispatcher->dispatch(
UserEvents::USER_USERGROUP_JOIN,
new UserGroupUserEvent($userGroup, $user)
);
$this->em->flush();
}
}
Which results in an insert of the user again, instead of a insert of the relationship.
Upvotes: 1
Views: 1018
Reputation: 1986
Is unclear which side is the owning side as based on what we read in the docs for doctrine:
For ManyToMany bidirectional relationships either side may be the owning side (the side that defines the @JoinTable and/or does not make use of the mappedBy attribute, thus using a default join table).
And in your case, the User table defines the join table but also declares "mappedBy" attribute which belongs in the owned side, not the owner.
Are you sure that the user is always an authenticated one, therefore one existing in the database?
Another thin, after reading here: http://docs.doctrine-project.org/en/2.1/cookbook/entities-in-session.html is that:
A frequent mistake is not to get the merged user object from the return value of EntityManager#merge(). The entity object passed to merge is not necessarily the same object that is returned from the method.
So in the first example:
$this->em->merge($user);
should become
$user = $this->em->merge($user);
Upvotes: 4