O
O
ostiwe2020-06-10 18:54:57
symfony
ostiwe, 2020-06-10 18:54:57

A circular reference has been detected when serializing the object of class how to solve?

Hello there are two classes (Entity)

user

<?php

namespace App\Entity;

use App\Repository\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass=UserRepository::class)
 * @ORM\Table(name="users")
 */
class User
{

  /* Битовые маски доступные пользователю */
  const CAN_READ = 1 << 1;
  const CAN_CREATE_POST = 1 << 2;
  const CAN_UPLOAD_FILES = 1 << 3;
  const CAN_CREATE_COMMENT = 1 << 4;
  const CAN_DELETE_COMMENT = 1 << 5;
  const CAN_WRITE_MESSAGES = 1 << 6;

  const USER_BLOCKED = 1 << 0;

  /**
   * @ORM\Id()
   * @ORM\GeneratedValue()
   * @ORM\Column(type="integer")
   */
  private $id;

  /**
   * @ORM\Column(type="string", length=255)
   */
  private $login;

  /**
   * @ORM\Column(type="string", length=255)
   */
  private $email;

  /**
   * @ORM\Column(type="string", length=255, nullable=true)
   */
  private $first_name;

  /**
   * @ORM\Column(type="string", length=255, nullable=true)
   */
  private $last_name;

  /**
   * @ORM\Column(type="integer")
   */
  private $mask;

  /**
   * @ORM\OneToMany(targetEntity=AccessToken::class, mappedBy="owner", orphanRemoval=true)
   */
  private $tokens;

  /**
   * @ORM\Column(type="string", length=255)
   */
  private $password;

  public function __construct()
  {
    $this->tokens = new ArrayCollection();
  }

  public function getId(): ?int
  {
    return $this->id;
  }

  public function getLogin(): ?string
  {
    return $this->login;
  }

  public function setLogin(string $login): self
  {
    $this->login = $login;

    return $this;
  }

  public function getEmail(): ?string
  {
    return $this->email;
  }

  public function setEmail(string $email): self
  {
    $this->email = $email;

    return $this;
  }

  public function getFirstName(): ?string
  {
    return $this->first_name;
  }

  public function setFirstName(?string $first_name): self
  {
    $this->first_name = $first_name;

    return $this;
  }

  public function getLastName(): ?string
  {
    return $this->last_name;
  }

  public function setLastName(?string $last_name): self
  {
    $this->last_name = $last_name;

    return $this;
  }

  public function getMask(): ?int
  {
    return $this->mask;
  }

  public function setMask(int $mask): self
  {
    $this->mask = $mask;

    return $this;
  }

  /**
   * @return Collection|AccessToken[]
   */
  public function getTokens(): Collection
  {
    return $this->tokens;
  }

  public function addToken(AccessToken $token): self
  {
    if (!$this->tokens->contains($token)) {
      $this->tokens[] = $token;
      $token->setOwner($this);
    }

    return $this;
  }

  public function removeToken(AccessToken $token): self
  {
    if ($this->tokens->contains($token)) {
      $this->tokens->removeElement($token);
      // set the owning side to null (unless already changed)
      if ($token->getOwner() === $this) {
        $token->setOwner(null);
      }
    }

    return $this;
  }

  public function getPassword(): ?string
  {
    return $this->password;
  }

  public function setPassword(string $password): self
  {
    $this->password = $password;

    return $this;
  }
}


AccessToken

<?php

namespace App\Entity;

use App\Repository\AccessTokenRepository;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass=AccessTokenRepository::class)
 */
class AccessToken
{
  /**
   * @ORM\Id()
   * @ORM\GeneratedValue()
   * @ORM\Column(type="integer")
   */
  private $id;

  /**
   * @ORM\ManyToOne(targetEntity=User::class, inversedBy="tokens")
   * @ORM\JoinColumn(nullable=false)
   */
  private $owner;

  /**
   * @ORM\Column(type="string", length=255)
   */
  private $value;

  /**
   * @ORM\Column(type="integer")
   */
  private $mask;

  /**
   * @ORM\Column(type="integer")
   */
  private $created;

  /**
   * @ORM\Column(type="integer")
   */
  private $expired;

  public function getId(): ?int
  {
    return $this->id;
  }

  public function getOwner(): ?User
  {
    return $this->owner;
  }

  public function setOwner(?User $owner): self
  {
    $this->owner = $owner;

    return $this;
  }

  public function getValue(): ?string
  {
    return $this->value;
  }

  public function setValue(string $value): self
  {
    $this->value = $value;

    return $this;
  }

  public function getMask(): ?int
  {
    return $this->mask;
  }

  public function setMask(int $mask): self
  {
    $this->mask = $mask;

    return $this;
  }

  public function getCreated(): ?int
  {
    return $this->created;
  }

  public function setCreated(int $created): self
  {
    $this->created = $created;

    return $this;
  }

  public function getExpired(): ?int
  {
    return $this->expired;
  }

  public function setExpired(int $expired): self
  {
    $this->expired = $expired;

    return $this;
  }

  public function generate()
  {
    try {
      $token = bin2hex(random_bytes(20));
    } catch (\Exception $e) {
      return false;
    }

    $this->value = $token;

    return $this;
  }
}



There is a route
route

/** @Route("/users") */
  public function getUsers()
  {
    $users = $this->getDoctrine()->getRepository(User::class)->findAll();
    return $this->json($users);
  }



When requesting this route, this error occurs: "A circular reference has been detected when serializing the object of class "App\Entity\User" (configured limit: 1)."

In the course of "experiments", I found that if the getOwner method is removed from the AccessToken, the error will disappear, however, this solution does not suit me.

Who can faced it? How to solve this problem?

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question