0
votes

I have a problem with the FOSUserBundle. A know problem : 'Unrecognized field: usernameCanonical for symfony2 FosUserbundle' when I try a login

AND

on schema update I get this error:

Duplicate definition of column 'username' on entity 'Acme\ProjectBundle\Entity\User' in a field or discriminator column mapping. 

I get this error ONLY IF I add the 'FOSUserBundle: ~' to settings of doctrine's mapping in the config.yml

I have tried a lot of solutions but I don't have resoved my problem :/ Please help me.

I have followed the FOS' team: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md

Before everything worked perfectly ...

I have Symfony 2.1.9

My config.yml:

doctrine:
dbal:
    default_connection: default
    connections:
        default:
            driver:   "%database_driver%"
            host:     "%database_host%"
            port:     "%database_port%"
            dbname:   "%database_name%"
            user:     "%database_user%"
            password: "%database_password%"
            charset:  UTF8
        service:
            driver:   "%database_driver2%"
            host:     "%database_host2%"
            port:     "%database_port2%"
            dbname:   "%database_name2%"
            user:     "%database_user2%"
            password: "%database_password2%"
            charset:  UTF8
orm:
    auto_generate_proxy_classes: "%kernel.debug%"
    #auto_mapping: true
    default_entity_manager: default
    entity_managers:
        default:
            metadata_cache_driver: apc
            result_cache_driver: apc
            query_cache_driver: apc
            connection: default
            mappings:
                FOSUserBundle: ~
                AcmeProjectBundle: {type: yml, dir: Resources/config/doctrine/ } #also tried wit '~'
fos_user:
    db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel'
    firewall_name: main
    user_class: Acme\ProjectBundle\Entity\User

My Acme\ProjectBundle\Entity\User.php:

namespace Acme\ProjectBundle\Entity;

 use FOS\UserBundle\Entity\User as BaseUser;
 use Doctrine\ORM\Mapping as ORM;
 use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
 use Symfony\Component\Validator\Constraints as Assert;
 use Symfony\Component\Security\Core\User\UserInterface;


 class User extends BaseUser implements UserInterface, \Serializable
 {
      const TYPE_ADMIN        = 0;
      const TYPE_USER         = 2;
      const TYPE_ARTIST       = 3;

/**
 * @var string $salt
 */
protected $salt;

/**
 * @var boolean $is_active
 */
private $is_active;
protected $id;


private $name;


protected $username;

protected $email;

/**
 * @var tinyint $type
 */
private $type;


protected $password;


private $description;


/**
 * Get id
 *
 * @return integer 
 */
public function getId()
{
    return $this->id;
}

/**
 * Set name
 *
 * @param string $name
 * @return User
 */
public function setName($name)
{
    $this->name = $name;

    return $this;
}

/**
 * Get name
 *
 * @return string 
 */
public function getName()
{
    return $this->name;
}

/**
 * Set type
 *
 * @param integer $type
 * @return User
 */
public function setType($type)
{
    $this->type = $type;

    return $this;
}

/**
 * Get type
 *
 * @return integer 
 */
public function getType()
{
    return $this->type;
}

/**
 * Set description
 *
 * @param string $description
 * @return User
 */
public function setDescription($description)
{
    $this->description = $description;

    return $this;
}

/**
 * Get description
 *
 * @return string 
 */
public function getDescription()
{
    return $this->description;
}

/**
 * Set username
 *
 * @param string $username
 * @return User
 */
public function setUsername($username)
{
    $this->username = $username;

    return $this;
}

/**
 * Get username
 *
 * @return string 
 */
public function getUsername()
{
    return $this->username;
}

/**
 * Set password
 *
 * @param string $password
 * @return User
 */
public function setPassword($password)
{
    $this->password = $password;

    return $this;
}

/**
 * Get password
 *
 * @return string 
 */
public function getPassword()
{
    return $this->password;
}

/**
 * Set email
 *
 * @param string $email
 * @return User
 */
public function setEmail($email)
{
    $this->email = $email;

    return $this;
}

/**
 * Get email
 *
 * @return string 
 */
public function getEmail()
{
    return $this->email;
}




public function isPasswordName()
{
    return ($this->name != $this->password);
}

public function isPassUsername()
{
    return ($this->password != $this->username);
}
/**
 * @var \DateTime $date
 */
private $date;


/**
 * Set date
 *
 * @param \DateTime $date
 * @return User
 */
public function setDate($date)
{
    $this->date = $date;

    return $this;
}

/**
 * Get date
 *
 * @return \DateTime 
 */
public function getDate()
{
    return $this->date;
}


private $updateDate;


/**
 * Set updateDate
 *
 * @param \DateTime $updateDate
 * @return User
 */
public function setUpdateDate($updateDate)
{
    $this->updateDate = $updateDate;

    return $this;
}

/**
 * Get updateDate
 *
 * @return \DateTime 
 */
public function getUpdateDate()
{
    return $this->updateDate;
}



public function setIsActive($value)
{
    $this->is_active = $value;

    return $this;
}

public function gettIsActive()
{
    return $this->is_active;

    return $this;
}


/**
 * Set salt
 *
 * @param string $salt
 * @return User
 */
public function setSalt($salt)
{
    $this->salt = $salt;

    return $this;
}

/**
 * Get salt
 *
 * @return string 
 */
public function getSalt()
{
    return $this->salt;
}


/**
 * @inheritDoc
 */
public function eraseCredentials()
{
}


public function __construct()
{
parent::__construct();
    $this->isActive = true;
    $this->salt = md5(uniqid(null, true));
}


public function getRoles()
{
    switch ($this->getType())
    {
            case 0:
                    return array('ROLE_ADMIN');
                    break;
            case 1:
            case 2:
            case 3:
                    return array('ROLE_USER');
                    break;

    }


}

/**
 * @see \Serializable::serialize()
 */
public function serialize()
{
    return serialize(array(
                    $this->id,
    ));
}

/**
 * @see \Serializable::unserialize()
 */
public function unserialize($serialized)
{
    list (
                    $this->id,
    ) = unserialize($serialized);
}
/**
 * @var integer $first_login
 */
private $first_login;


/**
 * Get is_active
 *
 * @return boolean 
 */
public function getIsActive()
{
    return $this->is_active;
}

/**
 * Set first_login
 *
 * @param integer $firstLogin
 * @return User
 */
public function setFirstLogin($firstLogin)
{
    $this->first_login = $firstLogin;

    return $this;
}

/**
 * Get first_login
 *
 * @return integer 
 */
public function getFirstLogin()
{
    return $this->first_login;
}
/**
 * @var \Doctrine\Common\Collections\ArrayCollection
 */
private $userPoints;





/**
 * @var integer $privacy
 */
private $privacy;


/**
 * Set privacy
 *
 * @param integer $privacy
 * @return User
 */
public function setPrivacy($privacy)
{
    $this->privacy = $privacy;

    return $this;
}

/**
 * Get privacy
 *
 * @return integer 
 */
public function getPrivacy()
{
    return $this->privacy;
}
/**
 * @var integer
 */
private $enable;


/**
 * Set enable
 *
 * @param integer $enable
 * @return User
 */
public function setEnable($enable)
{
    $this->enable = $enable;

    return $this;
}

/**
 * Get enable
 *
 * @return integer 
 */
public function getEnable()
{
    return $this->enable;
}
}

My security.yml

security:
firewalls:
    main:
        pattern: ^/
        form_login:
            provider: fos_userbundle
            login_path: /login
            use_forward: false
            check_path: /login_check
            csrf_provider: form.csrf_provider
        logout:       true
        anonymous:    true
providers:
    fos_userbundle:
        id: fos_user.user_provider.username

encoders:
    FOS\UserBundle\Model\UserInterface: sha512

role_hierarchy:
    ROLE_ADMIN:       ROLE_USER
    ROLE_SUPER_ADMIN: ROLE_ADMIN

access_control:
    - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/admin/, role: ROLE_ADMIN }
5
I'm not quite sure. But in your orm configuration uncomment auto_mapping:true.Johannes Klauß
thank you for your suggestion but does not solve the problem :(vincenzodb
Well the error states, that your definition of the column username happens twice. Search your project files for something like @ORM\Column(name = "username") or look for $username in your entities and check if there is a duplicate column definition.Johannes Klauß
the only occurrence is in the model class of the FOSUSerBundle. Maybe FOS need my User class empty... ?!vincenzodb

5 Answers

3
votes

It seems your version of the FOSUserBundle is not good ... I had the same problem with a 1.3.* that I solved just changing this to version "~2.0@dev".

You can check this looking at your "fos_user" table ; if it just contains a single "id" field, your User entity is not extending the right "FOS\Entity\User" object ... try to upgrade your required version of the bundle in your "composer.json" and then rebuild your tables (below a full HARD rebuild - data are lost):

php app/console doctrine:schema:drop --force
php app/console doctrine:schema:create

If your "fos_user" table have all required fields, then you're good.

2
votes

Review the docs on creating a use class: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md

Your User class should not be repeating all the properties (username etc) from the base class. It should only have the new properties like name and id.

And while you didn't show your doctrine mapping file, I'm guessing your probably duplicated everything in there is well? Only map the new properties.

1
votes

In fact, i guess, you should have some piece of code on config.yml as

fos_user:  
    db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel'
    firewall_name: main  
    user_class: Acme\ProjectBundle\Entity\User

and you should have no need to add sth. to orm settings for FOSUser.

0
votes
orm:
    auto_generate_proxy_classes: "%kernel.debug%"
    #auto_mapping: true
    default_entity_manager: default
    entity_managers:
       default:            
          // that's for APCu or APC
          metadata_cache_driver: apc
          result_cache_driver: apc
          query_cache_driver: apc

in dev env APC disabled, that's why you get this error. You have to comment it for dev or enable cacheClassLoader

0
votes

I had this trouble and applied PieroWbmstr's suggestion, and started using 2.0 instead of 1.3.6... with doctrine.orm.auto_mapping set to true in config.yml

Once I made the composer.json version switch and upgraded, my doctrine:schema:update instantly recognised the new fields as missing in the current database instance, and applied them.

The newer version of the user class within FOS/UserBundle doesn't seem to have any significant changes that would force the mapping to play nicely. Does anyone have an idea as to what the difference is in these two versions? Or more directly, why the older version somehow didn't let doctrine recognise it's xml mappings (hint: in both of my FOS/UserBundle versions, I had my local custom bundles set to use annotations).

Thanks