Symfony FormType PropertyAccessor.php错误

I am getting an error when saving data using a formType into a model that has a many to many relationship.

The error is

Catchable Fatal Error: Argument 1 passed to AppBundle\Entity\User::removeRole() must be an instance of AppBundle\Entity\Role, string given, called in /Code/project/vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php on line 616 and defined

What is the best way to inject the Role model into the form?

The model has the following:

/**
 * @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
 * @ORM\JoinTable(name="user_roles")
 */
private $roles;

/**
 * Remove role
 *
 * @param Role $role
 */
public function removeRole(Role $role)
{
    $this->roles->removeElement($role);
}

/**
 * Add role
 *
 * @param Role $role
 *
 * @return User
 */
public function addRole(Role $role)
{
    $this->roles[] = $role;

    return $this;
}

There is the reverse in Role

/**
 *  @ORM\ManyToMany(targetEntity="User", mappedBy="roles")
 */
private $users;

To save the data in the controller I have

    $user = new User();
    $form = $this->createForm(UserType::class, $user);
    $form->handleRequest($request);
    if( $form->isSubmitted() && $form->isValid() ){

        $encryptedPassword = $this->get('security.password_encoder')
            ->encodePassword($user, $user->getPlainPassword());
        $user->setPassword($encryptedPassword);

        $em = $this->getDoctrine()->getManager();
        $em->persist($user);
        $em->flush();
        return $this->redirect($this->generateUrl('user_list'));
    }
    return $this->render('user/new.html.twig', array('form' => $form->createView()));

And the FormType has

class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('name')
        ->add('email')
        ->add('username')
        ->add('plainPassword', RepeatedType::class, array(
            'type' => PasswordType::class,
            'invalid_message' => 'The password fields must match.',
            'options' => array('attr' => array('class' => 'password-field')),
            'required' => true,
            'first_options'  => array('label' => 'Password'),
            'second_options' => array('label' => 'Repeat Password'),
        ))
        ->add('roles', EntityType::class, array(
            'class' => 'AppBundle:Role',
            'choice_label' => 'name',
            'multiple'    => true
        ));
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle\Entity\User'
    ));
}

}

I have worked out and it was a little gotcha that was the issue is and may cause others the same.

It is because:

class User implements UserInterface

which requires

/**
 * @return mixed
 */
public function getRoles()
{
    return ARRAY|STRING;
}

To get around this I create:

/**
 * @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
 * @ORM\JoinTable(name="user_roles")
 */
private $userRoles;

Everything then comes of getUserRoles and works fine.