Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding relationship to an Entity couses weird ORM mapping error

In Symfony Api Platform application, using Maker Bundle to add a relationship field "Owner" to "Community" Entity coused all "Get" api calls to return the same error. This is a new project I use all the newest available version.

Request: curl -X 'GET'
'http://127.0.0.1:8000/api/communities?page=1'
-H 'accept: application/ld+json'

//Error

{
  "@id": "/api/errors/500",
  "@type": "hydra:Error",
  "title": "An error occurred",
  "detail": "Attempted to load class \"ClassMetadataInfo\" from namespace \"Doctrine\\ORM\\Mapping\".\nDid you forget a \"use\" statement for another namespace?",
  "status": 500,
  "type": "/errors/500",
  "trace": [
    {
      "file": "\\vendor\\api-platform\\core\\src\\Doctrine\\Orm\\Extension\\EagerLoadingExtension.php",
      "line": 98,
      "function": "joinRelations",
      "class": "ApiPlatform\\Doctrine\\Orm\\Extension\\EagerLoadingExtension",
      "type": "->"
    },
    {
      "file": "\\vendor\\api-platform\\core\\src\\Doctrine\\Orm\\Extension\\EagerLoadingExtension.php",
      "line": 53,
      "function": "apply",
      "class": "ApiPlatform\\Doctrine\\Orm\\Extension\\EagerLoadingExtension",
      "type": "->"
    },
// Community.php

namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use App\Repository\CommunityRepository;
use Doctrine\DBAL\Types\Types;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
use App\Entity\User;


#[ORM\Entity(repositoryClass: CommunityRepository::class)]
#[ApiResource(
    normalizationContext: ['groups' => ['community:read']],
    denormalizationContext: ['groups' => ['community:create', 'community:update']],
)]
#[ORM\Table(name: '`community`')]
#[UniqueEntity('name')]
class Community
{
    const STATUS_PUBLIC = 'public';
    const STATUS_PRIVATE = 'private';
    const STATUS_RESTRICTED = 'restricted';

    #[Groups(['community:read'])]
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[Assert\NotBlank]
    #[Groups(['community:read', 'community:create', 'community:update'])]
    #[ORM\Column(length: 50)]
    
    private ?string $name = null;

    // Address and name of given community
    #[Groups(['community:read', 'community:create', 'community:update'])]
    #[ORM\Column(type: Types::TEXT, nullable: true)]
    private ?string $description = null;

    // Amount of users of given community
    #[ORM\Column]
    #[Groups(['community:read'])]
    private ?int $numberOfUsers = 0;

    // Date of creation of given community
    #[Groups(['community:read'])]
    #[ORM\Column(type: Types::DATETIMETZ_MUTABLE)]
    private ?\DateTimeInterface $creation_time = null;

    // Status of given community; PUBLIC, PRIVATE, RESTRICTED
    #[Groups(['community:read', 'community:create', 'community:update'])]
    #[ORM\Column(type: 'string', length: 10)]
    private ?string $status = self::STATUS_PUBLIC;

    #[Groups(['community:read', 'community:create', 'community:update'])]
    #[ORM\ManyToOne(targetEntity: User::class ,inversedBy: 'owned_communites')]
    #[ORM\JoinColumn(nullable: false)]
    private ?User $owner = null;

    //getters and setters
// User Entity

namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Put;
use Doctrine\DBAL\Types\Types;
use App\Repository\UserRepository;
use App\State\PasswordHasher;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Serializer\Annotation\Groups;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;

use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
use App\Entity\Community;

#[ApiResource(
    operations: [
        new GetCollection(),
        new Post(processor: PasswordHasher::class, validationContext: ['groups' => ['Default', 'user:create']]),
        new Get(),
        new Put(processor: PasswordHasher::class),
        new Patch(processor: PasswordHasher::class),
        new Delete(),
    ],
    normalizationContext: ['groups' => ['user:read']],
    denormalizationContext: ['groups' => ['user:create', 'user:update']],
)]
#[ORM\Entity(repositoryClass: UserRepository::class)]
#[ORM\Table(name: '`user`')]
#[UniqueEntity('email')]
class User implements UserInterface, PasswordAuthenticatedUserInterface
{
    #[Groups(['user:read'])]
    #[ORM\Id]
    #[ORM\Column(type: 'integer')]
    #[ORM\GeneratedValue]
    private ?int $id = null;

    #[Assert\NotBlank]
    #[Assert\Email]
    #[Groups(['user:read', 'user:create', 'user:update'])]
    #[ORM\Column(length: 80, unique: true)]
    private ?string $email = null;

    #[ORM\Column]
    //DEBUG ONLY:
    //#[Groups(['user:read', 'user:create', 'user:update'])]
    private ?string $password = null;

    #[Assert\NotBlank(groups: ['user:create'])]
    #[Groups(['user:create', 'user:update'])]
    private ?string $plainPassword = null;

    #[ORM\Column(type: 'json')]
    private array $roles = [];

    #[Assert\NotBlank]
    #[Groups(['user:read', 'user:create', 'user:update'])]
    #[ORM\Column(length: 25)]
    private ?string $nickname = null;

    #[Assert\NotBlank]
    #[Groups(['user:read', 'user:create', 'user:update'])]
    #[ORM\Column(length: 30)]
    private ?string $login = null;

    #[Assert\NotBlank]
    #[Groups(['user:read', 'user:create', 'user:update'])]
    #[ORM\Column(type: Types::DATETIMETZ_MUTABLE)]
    private ?\DateTimeInterface $birthday = null;

    #[Groups(['user:read'])]
    #[ORM\Column(type: Types::DATETIMETZ_MUTABLE)]
    private ?\DateTimeInterface $creation_time = null;

    #[Groups(['user:read', 'user:create', 'user:update'])]
    #[ORM\OneToMany(targetEntity: Community::class, mappedBy: 'owner')]
    private Collection $owned_communites;
//getters and setters
like image 308
Matthew Avatar asked Jul 22 '26 22:07

Matthew


2 Answers

There is an issue open for this problem. I think it's related to a BC BREAK: Removed Doctrine\ORM\Mapping\ClassMetadataInfo class in 3.0. Revert to 2.latest should fix it for now.

like image 104
Dr. Gianluigi Zane Zanettini Avatar answered Jul 25 '26 12:07

Dr. Gianluigi Zane Zanettini


Something is completely broken in Relationships in the newest version of the stack. The error appears everytime you add connection between entities. You can either try downgrading each component of Doctrine one by one via composer or simply move to Laravel and create your API there. It's much less broken. Cheers!

like image 30
OmniSensei15 Avatar answered Jul 25 '26 10:07

OmniSensei15