I have a problem that i can't resolve. That's why i'm coming here.
On my website, an user can upload pictures and videos. When the user try to delete his account, he got a 500 error :
"SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails"
If i understood, i have to use "joinColumn" "onCascade" and "onDelete" (I want to keep the user's pictures and videos)
My User entity :
<?php
namespace App\Entity;
use App\Repository\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* #ORM\Entity(repositoryClass=UserRepository::class)
* #UniqueEntity(fields={"email"}, message="Cette adresse email est déjà utilisée.")
*/
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="boolean")
*/
private $isVerified = false;
/**
* #ORM\OneToMany(targetEntity=Picture::class, mappedBy="author")
*/
private $pictures;
/**
* #ORM\OneToMany(targetEntity=Video::class, mappedBy="author")
*/
private $videos;
/**
* #ORM\ManyToMany(targetEntity=Picture::class, mappedBy="fav")
*/
private $favoris;
/**
* #ORM\ManyToMany(targetEntity=Video::class, mappedBy="fav")
*/
private $fav;
public function __construct()
{
$this->pictures = new ArrayCollection();
$this->videos = new ArrayCollection();
$this->favoris = new ArrayCollection();
$this->fav = new ArrayCollection();
}
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;
}
/**
* Returning a salt is only needed, if you are not using a modern
* hashing algorithm (e.g. bcrypt or sodium) in your security.yaml.
*
* #see UserInterface
*/
public function getSalt(): ?string
{
return null;
}
/**
* #see UserInterface
*/
public function eraseCredentials()
{
// If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null;
}
public function isVerified(): bool
{
return $this->isVerified;
}
public function setIsVerified(bool $isVerified): self
{
$this->isVerified = $isVerified;
return $this;
}
/**
* #return Collection|Picture[]
*/
public function getPictures(): Collection
{
return $this->pictures;
}
public function addPicture(Picture $picture): self
{
if (!$this->pictures->contains($picture)) {
$this->pictures[] = $picture;
$picture->setAuthor($this);
}
return $this;
}
public function removePicture(Picture $picture): self
{
if ($this->pictures->removeElement($picture)) {
// set the owning side to null (unless already changed)
if ($picture->getAuthor() === $this) {
$picture->setAuthor(null);
}
}
return $this;
}
/**
* #return Collection|Video[]
*/
public function getVideos(): Collection
{
return $this->videos;
}
public function addVideo(Video $video): self
{
if (!$this->videos->contains($video)) {
$this->videos[] = $video;
$video->setAuthor($this);
}
return $this;
}
public function removeVideo(Video $video): self
{
if ($this->videos->removeElement($video)) {
// set the owning side to null (unless already changed)
if ($video->getAuthor() === $this) {
$video->setAuthor(null);
}
}
return $this;
}
/**
* #return Collection|Picture[]
*/
public function getFavoris(): Collection
{
return $this->favoris;
}
public function addFavori(Picture $favori): self
{
if (!$this->favoris->contains($favori)) {
$this->favoris[] = $favori;
$favori->addFav($this);
}
return $this;
}
public function removeFavori(Picture $favori): self
{
if ($this->favoris->removeElement($favori)) {
$favori->removeFav($this);
}
return $this;
}
/**
* #return Collection|Video[]
*/
public function getFav(): Collection
{
return $this->fav;
}
public function addFav(Video $fav): self
{
if (!$this->fav->contains($fav)) {
$this->fav[] = $fav;
$fav->addFav($this);
}
return $this;
}
public function removeFav(Video $fav): self
{
if ($this->fav->removeElement($fav)) {
$fav->removeFav($this);
}
return $this;
}
}
My Picture entity :
<?php
namespace App\Entity;
use App\Repository\PictureRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* #ORM\Entity(repositoryClass=PictureRepository::class)
*/
class Picture
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=150)
*/
private $title;
/**
* #ORM\Column(type="text")
*/
private $description;
/**
* #ORM\Column(type="string", length=255, unique=true)
* #Gedmo\Slug(fields={"title"})
*/
private $slug;
public function getSlug(): ?string
{
return $this->slug;
}
public function setSlug(string $slug): self
{
$this->slug = $slug;
return $this;
}
/**
* #ORM\Column(type="datetime")
*/
private $publication_date;
/**
* #ORM\ManyToOne(targetEntity=User::class, inversedBy="pictures")
* #ORM\JoinColumn(nullable=false)
*/
private $author;
/**
* #ORM\Column(type="string", length=150)
*/
private $category;
/**
* #ORM\Column(type="string", length=50)
*/
private $image;
/**
* #ORM\ManyToMany(targetEntity=User::class, inversedBy="favoris")
*/
private $fav;
public function __construct()
{
$this->fav = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(string $description): self
{
$this->description = $description;
return $this;
}
public function getPublicationDate(): ?\DateTimeInterface
{
return $this->publication_date;
}
public function setPublicationDate(\DateTimeInterface $publication_date): self
{
$this->publication_date = $publication_date;
return $this;
}
public function getAuthor(): ?User
{
return $this->author;
}
public function setAuthor(?User $author): self
{
$this->author = $author;
return $this;
}
public function getCategory(): ?string
{
return $this->category;
}
public function setCategory(string $category): self
{
$this->category = $category;
return $this;
}
public function getImage(): ?string
{
return $this->image;
}
public function setImage(string $image): self
{
$this->image = $image;
return $this;
}
/**
* #return Collection|User[]
*/
public function getFav(): Collection
{
return $this->fav;
}
public function addFav(User $fav): self
{
if (!$this->fav->contains($fav)) {
$this->fav[] = $fav;
}
return $this;
}
public function removeFav(User $fav): self
{
$this->fav->removeElement($fav);
return $this;
}
}
My Video entity :
<?php
namespace App\Entity;
use App\Repository\VideoRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass=VideoRepository::class)
*/
class Video
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=150)
*/
private $title;
/**
* #ORM\Column(type="text")
*/
private $description;
/**
* #ORM\Column(type="datetime")
*/
private $publication_date;
/**
* #ORM\ManyToOne(targetEntity=User::class, inversedBy="videos")
* #ORM\JoinColumn(nullable=false)
*/
private $author;
/**
* #ORM\Column(type="string", length=150)
*/
private $category;
/**
* #ORM\Column(type="string", length=50)
*/
private $vid;
/**
* #ORM\ManyToMany(targetEntity=User::class, inversedBy="fav")
*/
private $fav;
public function __construct()
{
$this->fav = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(string $description): self
{
$this->description = $description;
return $this;
}
public function getPublicationDate(): ?\DateTimeInterface
{
return $this->publication_date;
}
public function setPublicationDate(\DateTimeInterface $publication_date): self
{
$this->publication_date = $publication_date;
return $this;
}
public function getAuthor(): ?User
{
return $this->author;
}
public function setAuthor(?User $author): self
{
$this->author = $author;
return $this;
}
public function getCategory(): ?string
{
return $this->category;
}
public function setCategory(string $category): self
{
$this->category = $category;
return $this;
}
public function getVid(): ?string
{
return $this->vid;
}
public function setVid(string $vid): self
{
$this->vid = $vid;
return $this;
}
/**
* #return Collection|User[]
*/
public function getFav(): Collection
{
return $this->fav;
}
public function addFav(User $fav): self
{
if (!$this->fav->contains($fav)) {
$this->fav[] = $fav;
}
return $this;
}
public function removeFav(User $fav): self
{
$this->fav->removeElement($fav);
return $this;
}
}
If you want to - when deleting a user - delete all his pictures and videos as well, you can just add cascade delete to the associations:
/**
* #ORM\OneToMany(targetEntity=Picture::class, mappedBy="author", cascade={"delete"})
*/
private $pictures;
/**
* #ORM\OneToMany(targetEntity=Video::class, mappedBy="author", cascade={"delete"})
*/
private $videos;
If you instead want to keep them and just remove the associoation to the user, add ON DELETE SET NULL to your author_id foreign keys in picture and video tables:
/**
* #ORM\ManyToOne(targetEntity=User::class, inversedBy="videos")
* #ORM\JoinColumn(nullable=true, onDelete="SET NULL")
*/
private $author;
Then you have to assume in your code that $this->author can be null.
Related
I'm stuck with this error:
Mapping "paint_images" does not exist. The configuration for the class "App\Entity\Painting" is probably incorrect as the mapping to use for the field "imageFile" could not be found. I'm on symfony 5.4.10. Problem occurs when creating a new painting.
I put you the entity that where the problem would come from :
´´´
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use App\Repository\PeintureRepository;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\HttpFoundation\File\File;
use Doctrine\Common\Collections\ArrayCollection;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use App\Entity\Categorie;
/**
* #ORM\Entity(repositoryClass=PeintureRepository::class)
* #Vich\Uploadable
*/
class Peinture
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $nom;
/**
* #ORM\Column(type="decimal", precision=6, scale=2, nullable=true)
*/
private $largeur;
/**
* #ORM\Column(type="decimal", precision=6, scale=2, nullable=true)
*/
private $hauteur;
/**
* #ORM\Column(type="boolean")
*/
private $enVente;
/**
* #ORM\Column(type="decimal", precision=10, scale=2, nullable=true)
*/
private $prix;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
private $dateRealisation;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
private $date;
/**
* #ORM\Column(type="text")
*/
private $description;
/**
* #ORM\Column(type="boolean")
*/
private $portefolio;
/**
* #ORM\Column(type="string", length=255)
*/
private $slug;
/**
* #ORM\Column(type="string", length=255)
*/
private $file;
/**
* #Vich\UploadableField(mapping="peinture_images", fileNameProperty="file")
* #var File
*/
private $imageFile;
/**
* #ORM\ManyToOne(targetEntity=User::class, inversedBy="peintures")
* #ORM\JoinColumn(nullable=false)
*/
private $user;
/**
* #ORM\ManyToMany(targetEntity=Categorie::class, inversedBy="peintures")
*/
private $categorie;
/**
* #ORM\OneToMany(targetEntity=Commentaire::class, mappedBy="peinture")
*/
private $commentaires;
public function __construct()
{
$this->categorie = new ArrayCollection();
$this->commentaires = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getNom(): ?string
{
return $this->nom;
}
public function setNom(string $nom): self
{
$this->nom = $nom;
return $this;
}
public function getLargeur(): ?string
{
return $this->largeur;
}
public function setLargeur(?string $largeur): self
{
$this->largeur = $largeur;
return $this;
}
public function getHauteur(): ?string
{
return $this->hauteur;
}
public function setHauteur(?string $hauteur): self
{
$this->hauteur = $hauteur;
return $this;
}
public function isEnVente(): ?bool
{
return $this->enVente;
}
public function setEnVente(bool $enVente): self
{
$this->enVente = $enVente;
return $this;
}
public function getPrix(): ?string
{
return $this->prix;
}
public function setPrix(?string $prix): self
{
$this->prix = $prix;
return $this;
}
public function getDateRealisation(): ?\DateTimeInterface
{
return $this->dateRealisation;
}
public function setDateRealisation(?\DateTimeInterface $dateRealisation): self
{
$this->dateRealisation = $dateRealisation;
return $this;
}
public function getDate(): ?\DateTimeInterface
{
return $this->date;
}
public function setDate(?\DateTimeInterface $date): self
{
$this->date = $date;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(string $description): self
{
$this->description = $description;
return $this;
}
public function isPortefolio(): ?bool
{
return $this->portefolio;
}
public function setPortefolio(bool $portefolio): self
{
$this->portefolio = $portefolio;
return $this;
}
public function getSlug(): ?string
{
return $this->slug;
}
public function setSlug(string $slug): self
{
$this->slug = $slug;
return $this;
}
public function getFile(): ?string
{
return $this->file;
}
public function setFile(string $file): self
{
$this->file = $file;
return $this;
}
public function setImageFile(File $file=null)
{
$this->file = $file;
if($file) {
$this->date = new \DateTime('now');
}
}
public function getImageFile()
{
return $this->imageFile;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
/**
* #return Collection<int, Categorie>
*/
public function getCategorie(): Collection
{
return $this->categorie;
}
public function addCategorie(Categorie $categorie): self
{
if (!$this->categorie->contains($categorie)) {
$this->categorie[] = $categorie;
}
return $this;
}
public function removeCategorie(Categorie $categorie): self
{
$this->categorie->removeElement($categorie);
return $this;
}
/**
* #return Collection<int, Commentaire>
*/
public function getCommentaires(): Collection
{
return $this->commentaires;
}
public function addCommentaire(Commentaire $commentaire): self
{
if (!$this->commentaires->contains($commentaire)) {
$this->commentaires[] = $commentaire;
$commentaire->setPeinture($this);
}
return $this;
}
public function removeCommentaire(Commentaire $commentaire): self
{
if ($this->commentaires->removeElement($commentaire)) {
// set the owning side to null (unless already changed)
if ($commentaire->getPeinture() === $this) {
$commentaire->setPeinture(null);
}
}
return $this;
}
}
´´´
In my code, I have implemented OneToMany self-referencing relationship. I have initialized array collection in the constructor. When I send a query parent is added to the children. But when I try to return an object in the children or parent property I get not an Object but an Array collection string. The error looks like this:
App\Entity\Employee::getChildren(): Return value must be of type
Doctrine\Common\Collections\Collection, string returned
Here is my entity:
<?php
namespace App\Entity;
use App\Repository\EmployeeRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass=EmployeeRepository::class)
*/
class Employee
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="integer", nullable=true)
*/
private $parent_id;
/**
* #ORM\Column(type="string", length=30)
*/
private $firstName;
/**
* #ORM\Column(type="string", length=30)
*/
private $lastName;
/**
* #ORM\Column(type="string", length=40)
*/
private $position;
/**
* #ORM\Column(type="string", length=20)
*/
private $phoneNumber;
/**
* #ORM\Column(type="string", length=255)
*/
private $email;
/**
* #ORM\Column(type="integer")
*/
private $workExperience;
/**
* #ORM\Column(type="integer")
*/
private $levelOfKnowledge;
/**
* #ORM\Column(nullable=true)
* #ORM\OneToMany(targetEntity=Employee::class, mappedBy="parent")
*/
private $children;
/**
* #ORM\Column(nullable=true)
* #ORM\ManyToOne(targetEntity=Employee::class, inversedBy="children")
*/
private $parent;
public function __construct()
{
$this->children = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getFirstName(): ?string
{
return $this->firstName;
}
public function setFirstName(string $firstName): self
{
$this->firstName = $firstName;
return $this;
}
public function getLastName(): ?string
{
return $this->lastName;
}
public function setLastName(string $lastName): self
{
$this->lastName = $lastName;
return $this;
}
public function getPosition(): ?string
{
return $this->position;
}
public function setPosition(string $position): self
{
$this->position = $position;
return $this;
}
public function getPhoneNumber(): ?string
{
return $this->phoneNumber;
}
public function setPhoneNumber(string $phoneNumber): self
{
$this->phoneNumber = $phoneNumber;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getWorkExperience(): ?int
{
return $this->workExperience;
}
public function setWorkExperience(int $workExperience): self
{
$this->workExperience = $workExperience;
return $this;
}
public function getLevelOfKnowledge(): ?int
{
return $this->levelOfKnowledge;
}
public function setLevelOfKnowledge(int $levelOfKnowledge): self
{
$this->levelOfKnowledge = $levelOfKnowledge;
return $this;
}
public function getParent(): ?self
{
return $this->parent;
}
public function setParent(Employee $employee): void
{
$this->parent = $employee;
}
/**
* #return Collection|Employee[]|null
*/
public function getChildren(): Collection
{
dump($this->children);
return $this->children;
}
public function __toString(): string
{
return $this->children;
}
/**
* #return mixed
*/
public function getParentId()
{
return $this->parent_id;
}
/**
* #param mixed $parent_id
*/
public function setParentId($parent_id): void
{
$this->parent_id = $parent_id;
}
}
The problem lies in this part:
/**
* #ORM\Column(nullable=true)
* #ORM\OneToMany(targetEntity=Employee::class, mappedBy="parent")
*/
private $children;
as you've mapped your field both as a column and a relation. You must not use #Column along with #OneToMany as it's not even making sens - the children is not reflected in the database anyway.
I currently have the following error with my entity code, and I don't really understand why I am having this problem.
I only have it in the page of my create dashboard, while I don't call the images but only the heritages, and in the form everything works fine.
I have tried changing Collection to ArrayCollection but nothing has changed.
<?php
namespace App\Entity;
use App\Repository\PatrimoineRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity(repositoryClass=PatrimoineRepository::class)
*/
class Patrimoine
{
/**
* #ORM\Id
* #ORM\Column(type="string", unique=true)
* #ORM\GeneratedValue("UUID")
*/
private ?string $id = null;
/**
* #ORM\Column(type="string", length=255)
*/
private ?string $name;
/**
* #ORM\Column(type="string", length=255)
*/
private ?string $description;
/**
* #ORM\Column(type="json")
* #Assert\Collection(
* fields={
* "lat" = {
* #Assert\NotBlank,
* #Assert\Regex("/^(-?(?:1[0-7]|[1-9])?\d(?:\.\d{1,18})?|180(?:\.0{1,18})?)$/")
* },
* "lng" = {
* #Assert\NotBlank,
* #Assert\Regex("/^(-?[1-8]?\d(?:\.\d{1,18})?|90(?:\.0{1,18})?)$/")
* },
* },
* missingFieldsMessage="Le champs {{ field }} est manquant"
* )
*/
private array $localisation = [];
/**
* #ORM\Column(type="datetime_immutable")
*/
private ?\DateTimeImmutable $created_at;
/**
* #ORM\Column(type="string", length=255)
*/
private ?string $statut;
/**
* #ORM\ManyToOne(targetEntity=CategoryPatrimoine::class, inversedBy="patrimoines")
* #ORM\JoinColumn(nullable=false)
*/
private ?CategoryPatrimoine $category;
/**
* #ORM\Column(type="string", length=255)
*/
private ?string $visibility;
/**
* #ORM\ManyToOne(targetEntity=User::class, inversedBy="patrimoines")
* #ORM\JoinColumn(nullable=false)
*/
private ?User $author;
/**
* #ORM\OneToMany(targetEntity=Image::class, mappedBy="patrimoine", orphanRemoval=true)
*/
private ArrayCollection $images;
public function __construct()
{
$this->setCreatedAt(new \DateTimeImmutable());
$this->images = new ArrayCollection();
}
public function getId(): ?string
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(string $description): self
{
$this->description = $description;
return $this;
}
public function getLocalisation(): ?array
{
return $this->localisation;
}
public function setLocalisation(array $localisation): self
{
$this->localisation = $localisation;
return $this;
}
public function getCreatedAt(): ?\DateTimeImmutable
{
return $this->created_at;
}
public function setCreatedAt(\DateTimeImmutable $created_at): self
{
$this->created_at = $created_at;
return $this;
}
public function getStatut(): ?string
{
return $this->statut;
}
public function setStatut(string $statut): self
{
$this->statut = $statut;
return $this;
}
public function getCategory(): ?CategoryPatrimoine
{
return $this->category;
}
public function setCategory(?CategoryPatrimoine $category): self
{
$this->category = $category;
return $this;
}
public function getVisibility(): ?string
{
return $this->visibility;
}
public function setVisibility(string $visibility): self
{
$this->visibility = $visibility;
return $this;
}
public function getAuthor(): ?User
{
return $this->author;
}
public function setAuthor(?User $author): self
{
$this->author = $author;
return $this;
}
/**
* #return Collection|Image[]
*/
public function getImages(): Collection
{
return $this->images;
}
public function addImage(Image $image): self
{
if (!$this->images->contains($image)) {
$this->images[] = $image;
$image->setPatrimoine($this);
}
return $this;
}
public function removeImage(Image $image): self
{
// set the owning side to null (unless already changed)
if ($this->images->removeElement($image) && $image->getPatrimoine() === $this) {
$image->setPatrimoine(null);
}
return $this;
}
}
I faced a similar problem too. You must declare the property as Collection (interface), not as implementation ArrayCollection because Doctrine ORM uses PersistentCollection when picks up data from database but you declare the property as ArrayCollection, and type mismatch happens.
class SomeEntity {
private Collection $items;
// all other code
}
I just realized that the typing of $ images was wrong, it was "ArrayCollection" whereas it must be "Collection"
beginner here i'm trying to do an API with Api-platform and Symfony. Actually i want to create my database schema and start testing it but when using php bin/console doctrine:schema:validate, i got this error and i cant figure out how to fix it : The table with name 'mydb.appartment_user' already exists
Unfortunately i didnt found an answer on google to my problem :'(
Here is my appartement entity :
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Repository\AppartmentRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ApiResource()
* #ORM\Entity(repositoryClass=AppartmentRepository::class)
*/
class Appartment
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $adress;
/**
* #ORM\Column(type="string", length=255)
*/
private $latitude;
/**
* #ORM\Column(type="string", length=255)
*/
private $longitude;
/**
* #ORM\ManyToMany(targetEntity=User::class, inversedBy="occupied_appartments")
*/
private $current_tenant;
/**
* #ORM\ManyToMany(targetEntity=User::class, inversedBy="rented_appartments")
*/
private $landlord;
/**
* #ORM\OneToOne(targetEntity=Lock::class, cascade={"persist", "remove"})
* #ORM\JoinColumn(nullable=false)
*/
private $lock_id;
public function __construct()
{
$this->current_tenant = new ArrayCollection();
$this->landlord = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getAdress(): ?string
{
return $this->adress;
}
public function setAdress(string $adress): self
{
$this->adress = $adress;
return $this;
}
public function getLatitude(): ?string
{
return $this->latitude;
}
public function setLatitude(string $latitude): self
{
$this->latitude = $latitude;
return $this;
}
public function getLongitude(): ?string
{
return $this->longitude;
}
public function setLongitude(string $longitude): self
{
$this->longitude = $longitude;
return $this;
}
/**
* #return Collection|User[]
*/
public function getCurrentTenant(): Collection
{
return $this->current_tenant;
}
public function addCurrentTenant(User $currentTenant): self
{
if (!$this->current_tenant->contains($currentTenant)) {
$this->current_tenant[] = $currentTenant;
}
return $this;
}
public function removeCurrentTenant(User $currentTenant): self
{
$this->current_tenant->removeElement($currentTenant);
return $this;
}
/**
* #return Collection|User[]
*/
public function getLandlord(): Collection
{
return $this->landlord;
}
public function addLandlord(User $landlord): self
{
if (!$this->landlord->contains($landlord)) {
$this->landlord[] = $landlord;
}
return $this;
}
public function removeLandlord(User $landlord): self
{
$this->landlord->removeElement($landlord);
return $this;
}
public function getLockId(): ?Lock
{
return $this->lock_id;
}
public function setLockId(Lock $lock_id): self
{
$this->lock_id = $lock_id;
return $this;
}
}
and my user entity :
<?php
namespace App\Entity;
use App\Repository\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* #ORM\Entity(repositoryClass=UserRepository::class)
* #ORM\Table(name="`user`")
*/
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 $firstname;
/**
* #ORM\Column(type="string", length=255)
*/
private $lastname;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $profile_picture;
/**
* #ORM\ManyToMany(targetEntity=Appartment::class, mappedBy="current_tenant")
*/
private $occupied_appartments;
/**
* #ORM\ManyToMany(targetEntity=Appartment::class, mappedBy="landlord")
*/
private $rented_appartments;
/**
* #ORM\ManyToMany(targetEntity=Rental::class, mappedBy="tenant_id")
*/
private $tenant_rentals;
/**
* #ORM\ManyToMany(targetEntity=Rental::class, mappedBy="landlord_id")
*/
private $landlord_rentals;
public function __construct()
{
$this->occupied_appartments = new ArrayCollection();
$this->rented_appartments = new ArrayCollection();
$this->tenant_rentals = new ArrayCollection();
$this->landlord_rentals = new ArrayCollection();
}
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 getFirstname(): ?string
{
return $this->firstname;
}
public function setFirstname(string $firstname): self
{
$this->firstname = $firstname;
return $this;
}
public function getLastname(): ?string
{
return $this->lastname;
}
public function setLastname(string $lastname): self
{
$this->lastname = $lastname;
return $this;
}
public function getProfilePicture(): ?string
{
return $this->profile_picture;
}
public function setProfilePicture(?string $profile_picture): self
{
$this->profile_picture = $profile_picture;
return $this;
}
/**
* #return Collection|Appartment[]
*/
public function getOccupiedAppartments(): Collection
{
return $this->occupied_appartments;
}
public function addOccupiedAppartment(Appartment $occupied_appartments): self
{
if (!$this->occupied_appartments->contains($occupied_appartments)) {
$this->occupied_appartments[] = $occupied_appartments;
$occupied_appartments->addCurrentTenant($this);
}
return $this;
}
public function removeOccupiedAppartment(Appartment $occupied_appartments): self
{
if ($this->occupied_appartments->removeElement($occupied_appartments)) {
$occupied_appartments->removeCurrentTenant($this);
}
return $this;
}
/**
* #return Collection|Appartment[]
*/
public function getRentedAppartments(): Collection
{
return $this->rented_appartments;
}
public function addRentedAppartment(Appartment $rentedAppartment): self
{
if (!$this->rented_appartments->contains($rentedAppartment)) {
$this->rented_appartments[] = $rentedAppartment;
$rentedAppartment->addLandlord($this);
}
return $this;
}
public function removeRentedAppartment(Appartment $rentedAppartment): self
{
if ($this->rented_appartments->removeElement($rentedAppartment)) {
$rentedAppartment->removeLandlord($this);
}
return $this;
}
/**
* #return Collection|Rental[]
*/
public function getTenantRentals(): Collection
{
return $this->tenant_rentals;
}
public function addTenantRental(Rental $tenantRental): self
{
if (!$this->tenant_rentals->contains($tenantRental)) {
$this->tenant_rentals[] = $tenantRental;
$tenantRental->addTenantId($this);
}
return $this;
}
public function removeTenantRental(Rental $tenantRental): self
{
if ($this->tenant_rentals->removeElement($tenantRental)) {
$tenantRental->removeTenantId($this);
}
return $this;
}
/**
* #return Collection|Rental[]
*/
public function getLandlordRentals(): Collection
{
return $this->landlord_rentals;
}
public function addLandlordRental(Rental $landlordRental): self
{
if (!$this->landlord_rentals->contains($landlordRental)) {
$this->landlord_rentals[] = $landlordRental;
$landlordRental->addLandlordId($this);
}
return $this;
}
public function removeLandlordRental(Rental $landlordRental): self
{
if ($this->landlord_rentals->removeElement($landlordRental)) {
$landlordRental->removeLandlordId($this);
}
return $this;
}
}
I tried to clear-cache and to force but it didnt work.
Thank's in advance for help and ask me if I forget any details !
add a JoinTable annotation for properties which have ManyToMany relation in Appartment entity
/**
* #ORM\ManyToMany(targetEntity=User::class, inversedBy="occupied_appartments")
* #ORM\JoinTable(name="appartment_current_tenant")
*/
private $current_tenant;
/**
* #ORM\ManyToMany(targetEntity=User::class, inversedBy="rented_appartments")
* #ORM\JoinTable(name="appartment_landlord")
*/
private $landlord;
I am having trouble in debugging mapping error of Entity.
When I run php bin/console doctrine:schema:validate, It shows the error , which is as follow
[FAIL] The entity-class App\Entity\Company mapping is invalid:
The association App\Entity\Company#policies refers to the owning side field App\Entity\Policy#company_id which does not exist.
I tried this post ( Entity class mapping is invalid) which is pretty much same with me but seems like not working.
This is my Company Entity
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Timestampable\Traits\TimestampableEntity;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity(repositoryClass="App\Repository\CompanyRepository")
*/
class Company
{
use TimestampableEntity;
const STATUS_ACTIVE = "ACTIVE";
const STATUS_STAGING = "STAGING";
const STATUS_INACTIVE = "INACTIVE";
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
* #Assert\NotBlank
*/
private $name;
/**
* #ORM\Column(type="string", length=255)
* #Assert\NotBlank
*/
private $address;
/**
* #ORM\Column(type="string", length=255)
* #Assert\NotBlank
*/
private $email;
/**
* #ORM\Column(type="string", length=255)
*/
private $status;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $logo;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Policy", mappedBy="company_id")
*/
private $policies;
/**
* #ORM\Column(type="string", length=255)
*/
private $url;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="companies")
*/
private $user;
public function __construct()
{
$this->policies = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getAddress(): ?string
{
return $this->address;
}
public function setAddress(string $address): self
{
$this->address = $address;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getLogo(): ?string
{
return $this->logo;
}
public function setLogo(string $logo): self
{
$this->logo = $logo;
return $this;
}
/**
* #return Collection|Policy[]
*/
public function getPolicies(): Collection
{
return $this->policies;
}
public function addPolicy(Policy $policy): self
{
if (!$this->policies->contains($policy)) {
$this->policies[] = $policy;
$policy->setCompany($this);
}
return $this;
}
public function removePolicy(Policy $policy): self
{
if ($this->policies->contains($policy)) {
$this->policies->removeElement($policy);
// set the owning side to null (unless already changed)
if ( $policy->getCompany() === $this) {
$policy->setCompany(null);
}
}
return $this;
}
public function getUrl(): ?string
{
return $this->url;
}
public function setUrl(string $url): self
{
$this->url = $url;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
public function getStatus(): ?string
{
return $this->status;
}
public function setStatus(string $status): self
{
$this->status = $status;
return $this;
}
}
And this is my Policy Entity
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Timestampable\Traits\TimestampableEntity;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity(repositoryClass="App\Repository\PolicyRepository")
*/
class Policy
{
use TimestampableEntity;
const VEH_TYPE_MINIBUS = "Minibus";
const VEH_TYPE_FOUR_WHEEL = "4x4";
const VEH_TYPE_CAR = "Car";
const VEH_PURPOSE_PERSONAL = "Personal";
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
* #Assert\NotBlank
*/
private $ref_id;
/**
* #ORM\Column(type="string", length=255)
*/
private $policy_code;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Company")
* #ORM\JoinColumn(name="company_id", nullable=false, referencedColumnName="id")
*/
private $company;
/**
* #ORM\Column(type="string", length=255)
* #Assert\NotBlank
*/
private $status;
/**
* #ORM\Column(type="datetime")
* #Assert\NotBlank
*/
private $fromDate;
/**
* #ORM\Column(type="datetime")
* #Assert\NotBlank
*/
private $toDate;
/**
* #ORM\Column(type="string", length=255)
*/
private $vehicle_type;
/**
* #ORM\Column(type="string", length=255)
*/
private $purpose;
/**
* #ORM\Column(type="float",scale=2)
*/
private $total_amt;
/**
* #ORM\Column(type="float", scale=2)
*/
private $cover_amt;
/**
* #ORM\Column(type="float", scale=2)
*/
private $discount;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Customer", inversedBy="policies")
*/
private $customer;
public function getId(): ?int
{
return $this->id;
}
public function getRefId(): ?string
{
return $this->ref_id;
}
public function setRefId(string $ref_id): self
{
$this->ref_id = $ref_id;
return $this;
}
public function getStatus(): ?string
{
return $this->status;
}
public function setStatus(string $status): self
{
$this->status = $status;
return $this;
}
public function getFromDate(): ?\DateTimeInterface
{
return $this->fromDate;
}
public function setFromDate(\DateTimeInterface $fromDate): self
{
$this->fromDate = $fromDate;
return $this;
}
public function getToDate(): ?\DateTimeInterface
{
return $this->toDate;
}
public function setToDate(\DateTimeInterface $toDate): self
{
$this->toDate = $toDate;
return $this;
}
public function getTotalAmt(): ?float
{
return $this->total_amt;
}
public function setTotalAmt(float $total_amt): self
{
$this->total_amt = $total_amt;
return $this;
}
public function getCoverAmt(): ?float
{
return $this->cover_amt;
}
public function setCoverAmt(float $cover_amt): self
{
$this->cover_amt = $cover_amt;
return $this;
}
public function getCompany(): ?Company
{
return $this->company;
}
public function setCompany(?Company $company): self
{
$this->company = $company;
return $this;
}
public function getCustomer(): ?Customer
{
return $this->customer;
}
public function setCustomer(?Customer $customer): self
{
$this->customer = $customer;
return $this;
}
public function getVehicleType(): ?string
{
return $this->vehicle_type;
}
public function setVehicleType(string $vehicle_type): self
{
$this->vehicle_type = $vehicle_type;
return $this;
}
public function getPurpose(): ?string
{
return $this->purpose;
}
public function setPurpose(string $purpose): self
{
$this->purpose = $purpose;
return $this;
}
public function getDiscount(): ?float
{
return $this->discount;
}
public function setDiscount(float $discount): self
{
$this->discount = $discount;
return $this;
}
public function getPolicyCode(): ?string
{
return $this->policy_code;
}
public function setPolicyCode(string $policy_code): self
{
$this->policy_code = $policy_code;
return $this;
}
}
company_id does not exist in the entity only in the table. So try mappedBy="company instead? Hope it helps!