J'ai une méthode de contrôleur sur laquelle je travaille pour mon entité Order
创建一个插入方法,它与 User
L'entité a une relation et un utilisateur peut avoir plusieurs commandes, maintenant, lorsque je crée la commande et y configure l'utilisateur, lorsque je ne la modifie pas, la doctrine va essayer de mettre à jour l'utilisateur et je me demande ce que je fais de mal
Ma méthode contrôleur
#[Route('/new', name: 'new', methods: ['POST'])] public function order( Request $request, ServiceRepository $serviceRepository, EntityManagerInterface $manager ): JsonResponse { $data = json_decode(json: $request->getContent()); //get service if (!property_exists($data, 'service')) return $this->json(['status' => false, 'message' => 'service is required']); $service = $serviceRepository->find($data->service); $order = new Order(); $order->setUser($this->getUser()); $order->setCreatedAt(new \DateTimeImmutable()); $order->setTotal(0); $order->setStatus(Order::STATUS_OPEN); $order->setService($service); $manager->persist($order); $manager->flush(); return $this->json(['status' => true]); }
Mon entité utilisateur
<?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\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Validator\Constraints as Assert; #[ORM\Entity(repositoryClass: UserRepository::class)] #[UniqueEntity('email', message: 'This Email Is Taken')] #[ORM\Table(name: '`user`')] class User implements UserInterface, PasswordAuthenticatedUserInterface { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; #[ORM\Column(length: 180, unique: true)] #[Assert\NotBlank, Assert\Email] private ?string $email = null; #[ORM\Column] private array $roles = []; /** * @var ?string The hashed password */ #[ORM\Column] #[Assert\NotBlank] private ?string $password = null; #[ORM\Column(length: 255)] #[Assert\NotBlank] private ?string $name = null; #[ORM\Column(length: 255, nullable: true)] private ?string $password_token = null; #[ORM\Column(nullable: true)] private ?\DateTimeImmutable $password_time = null; #[ORM\Column] private ?\DateTimeImmutable $created_at = null; #[ORM\Column(nullable: true)] private ?\DateTimeImmutable $updated_at = null; #[ORM\OneToMany(mappedBy: 'user', targetEntity: Order::class, orphanRemoval: true)] private Collection $total; public function __construct() { $this->total = 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 getUserIdentifier(): string { return (string) $this->email; } /** * @deprecated since Symfony 5.3, use getUserIdentifier instead */ 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 PasswordAuthenticatedUserInterface */ public function getPassword(): ?string { return $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() { unset($this->password, $this->roles, $this->access_token, $this->refresh_token, $this->updated_at); } public function getName(): ?string { return $this->name; } public function setName(string $name): self { $this->name = $name; 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 getUpdatedAt(): ?\DateTimeImmutable { return $this->updated_at; } public function setUpdatedAt(?\DateTimeImmutable $updated_at): self { $this->updated_at = $updated_at; return $this; } /** * @return string|null */ public function getPasswordToken(): ?string { return $this->password_token; } /** * @param string|null $password_token */ public function setPasswordToken(?string $password_token): void { $this->password_token = $password_token; } /** * @return \DateTimeImmutable|null */ public function getPasswordTime(): ?\DateTimeImmutable { return $this->password_time; } /** * @param \DateTimeImmutable|null $password_time */ public function setPasswordTime(?\DateTimeImmutable $password_time): void { $this->password_time = $password_time; } /** * @return Collection<int, Order> */ public function getTotal(): Collection { return $this->total; } public function addTotal(Order $total): self { if (!$this->total->contains($total)) { $this->total->add($total); $total->setUser($this); } return $this; } public function removeTotal(Order $total): self { if ($this->total->removeElement($total)) { // set the owning side to null (unless already changed) if ($total->getUser() === $this) { $total->setUser(null); } } return $this; } }
et mon entité de commande
<?php namespace App\Entity; use App\Repository\OrderRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: OrderRepository::class)] #[ORM\Table(name: '`order`')] class Order { public const STATUS_OPEN = 'open'; public const STATUS_AWAITING_PAYMENT = 'awaiting_payment'; public const STATUS_PAYMENT_VALIDATED = 'payment_validated'; public const STATUS_PAYMENT_CANCELLED = 'payment_cancelled'; public const STATUS_COMPLETED = 'completed'; #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; #[ORM\ManyToOne(inversedBy: 'total')] #[ORM\JoinColumn(nullable: false)] private ?User $user = null; #[ORM\Column] private ?float $total = null; #[ORM\Column(length: 255)] private ?string $status = null; #[ORM\Column] private ?\DateTimeImmutable $created_at = null; #[ORM\Column(nullable: true)] private ?\DateTimeImmutable $updated_at = null; #[ORM\OneToMany(mappedBy: 'parent', targetEntity: OrderItem::class, orphanRemoval: true)] private Collection $activity; #[ORM\ManyToOne(inversedBy: 'orders')] #[ORM\JoinColumn(nullable: false)] private ?Service $service = null; public function __construct() { $this->activity = new ArrayCollection(); } public function getId(): ?int { return $this->id; } public function getUser(): ?User { return $this->user; } public function setUser(?User $user): self { $this->user = $user; return $this; } public function getTotal(): ?float { return $this->total; } public function setTotal(float $total): self { $this->total = $total; return $this; } public function getStatus(): ?string { return $this->status; } public function setStatus(string $status): self { $this->status = $status; 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 getUpdatedAt(): ?\DateTimeImmutable { return $this->updated_at; } public function setUpdatedAt(?\DateTimeImmutable $updated_at): self { $this->updated_at = $updated_at; return $this; } /** * @return Collection<int, OrderItem> */ public function getActivity(): Collection { return $this->activity; } public function addActivity(OrderItem $activity): self { if (!$this->activity->contains($activity)) { $this->activity->add($activity); $activity->setParent($this); } return $this; } public function removeActivity(OrderItem $activity): self { if ($this->activity->removeElement($activity)) { // set the owning side to null (unless already changed) if ($activity->getParent() === $this) { $activity->setParent(null); } } return $this; } public function getService(): ?Service { return $this->service; } public function setService(?Service $service): self { $this->service = $service; return $this; } }
J'ai donc essayé de sauvegarder la commande, puis j'ai enregistré l'élément de campagne en utilisant l'identifiant de la commande qui est la commande enregistrée ci-dessus, mais cela a échoué et m'a donné une erreur de contrainte 执行查询时发生异常: SQLSTATE[23000]: 完整性约束违规:1048 列“角色”不能为空
Après le débogage, j'ai découvert que la doctrine ici souhaite mettre à jour mon utilisateur, mais j'ai apporté 0 modification à l'utilisateur, alors pourquoi dois-je le mettre à jour ?
Alors les gars, j'ai oublié de répondre à cette question après avoir trouvé la réponse, comme vous pouvez le voir dans mon entité Utilisateur, j'ai la méthode Erase Credentials
J'ai eu un malentendu sur le fait que j'appelais cette méthode avant de renvoyer l'utilisateur dans la requête API, mais elle a également été appelée avant l'actualisation, alors soyez prudent