I have class "etudiant" extends from user. the problem is when i try to login/logout with an "etudiant" account, i have this message : You cannot refresh a user from the EntityUserProvider that does not contain an identifier. The user object has to be serialized with its own identifier mapped by Doctrine.
User Entity :
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"user" = "User" , "etudiant" = "Etudiant"})
*/
class User implements UserInterface
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=180, unique=true)
*/
private $email;
/**
* @ORM\Column(type="json")
*/
private $roles = [];
/**
* @var string The hashed password
* @ORM\Column(type="string")
*/
private $password;
/**
* @ORM\Column(type="string", length=255)
*/
private $nom;
/**
* @ORM\Column(type="string", length=255)
*/
private $prenom;
public function getId(): ?int
{
return $this->id;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
/**
* A visual identifier that represents this user.
*
* @see UserInterface
*/
public function getUsername(): string
{
return (string) $this->email;
}
/**
* @see UserInterface
*/
public function getRoles(): array
{
$roles = $this->roles;
// guarantee every user at least has ROLE_USER
$roles[] = 'ROLE_USER';
return array_unique($roles);
}
public function setRoles(array $roles): self
{
$this->roles = $roles;
return $this;
}
/**
* @see UserInterface
*/
public function getPassword(): string
{
return (string) $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
/**
* @see UserInterface
*/
public function getSalt()
{
// not needed when using the "bcrypt" algorithm in security.yaml
}
/**
* @see UserInterface
*/
public function eraseCredentials()
{
// If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null;
}
public function getNom(): ?string
{
return $this->nom;
}
public function setNom(string $nom): self
{
$this->nom = $nom;
return $this;
}
public function getPrenom(): ?string
{
return $this->prenom;
}
public function setPrenom(string $prenom): self
{
$this->prenom = $prenom;
return $this;
}
}
Etudiant Entity
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\AttributeOverride;
use Doctrine\ORM\Mapping\Column;
/**
* @ORM\Entity(repositoryClass="App\Repository\EtudiantRepository")
* @ORM\AttributeOverrides({
* @AttributeOverride(name="id",
* column=@Column(
* name = "id",
* type = "integer",
* length = 140
* )
* )
* })
*/
class Etudiant extends User
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="date")
*/
private $date_naissance;
/**
* @ORM\Column(type="integer")
*/
private $sexe;
/**
* @ORM\Column(type="string", length=255)
*/
private $ville;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Encadrant", inversedBy="etudiants")
*/
private $encadrant;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Formation", inversedBy="etudiants")
* @ORM\JoinColumn(nullable=false)
*/
private $formation;
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Stage", mappedBy="etudiant")
*/
private $stages;
protected $discr = 'etudiant';
public function __construct()
{
$this->stages = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getDateNaissance(): ?\DateTimeInterface
{
return $this->date_naissance;
}
public function setDateNaissance(\DateTimeInterface $date_naissance): self
{
$this->date_naissance = $date_naissance;
return $this;
}
public function getSexe(): ?int
{
return $this->sexe;
}
public function setSexe(int $sexe): self
{
$this->sexe = $sexe;
return $this;
}
public function getVille(): ?string
{
return $this->ville;
}
public function setVille(string $ville): self
{
$this->ville = $ville;
return $this;
}
public function getEncadrant(): ?Encadrant
{
return $this->encadrant;
}
public function setEncadrant(?Encadrant $encadrant): self
{
$this->encadrant = $encadrant;
return $this;
}
public function getFormation(): ?Formation
{
return $this->formation;
}
public function setFormation(?Formation $formation): self
{
$this->formation = $formation;
return $this;
}
/**
* @return Collection|Stage[]
*/
public function getStages(): Collection
{
return $this->stages;
}
public function addStage(Stage $stage): self
{
if (!$this->stages->contains($stage)) {
$this->stages[] = $stage;
$stage->addEtudiant($this);
}
return $this;
}
public function removeStage(Stage $stage): self
{
if ($this->stages->contains($stage)) {
$this->stages->removeElement($stage);
$stage->removeEtudiant($this);
}
return $this;
}
}
Security.yaml
security:
encoders:
App\Entity\User:
algorithm: auto
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: lazy
provider: app_user_provider
guard:
authenticators:
- App\Security\LoginFormAuthenticator
logout:
path: app_logout
# where to redirect after logout
# target: app_any_route
access_denied_handler: App\Security\AccessDeniedHandler
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#firewalls-authentication
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
access_control:
# - { path: '^/admin', roles: [ROLE_SUPER_ADMIN, ROLE_ADMIN]}
- { path: '^/admin', roles: ROLE_ADMIN}
- { path: ^/front, roles: ROLE_ETUDIANT }
Error : can't found any solution. How can I resolve this problem. Thanks a lot
Solution is to remove the override in Entity Etudiant
* @ORM\AttributeOverrides({
* @AttributeOverride(name="id",
* column=@Column(
* name = "id",
* type = "integer",
* length = 140
* )
* )
* })
and remove the methode getId() from Entity Etudiant