question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Graphql & DTO , with "Internal server error" "The manager for POPO Output must be an EntityManager"

See original GitHub issue

Hi , (i use 2.5.4)

when i do:

query {
  recipeCategories {
    name
    recipes {
      name
    }
  }
}

i have the error “The manager for App\Dto\RecipeCategoryOutput must be an EntityManager”

<?php

namespace App\Entity;

use Ramsey\Uuid\Uuid;
use App\Dto\RecipeCategoryInput;
use Doctrine\ORM\Mapping as ORM;
use App\Dto\RecipeCategoryOutput;
use Doctrine\Common\Collections\Collection;
use ApiPlatform\Core\Annotation\ApiProperty;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ApiResource(
 *   input=RecipeCategoryInput::class,
 *   output=RecipeCategoryOutput::class
 * )
 * @ORM\Table(name="o_recipe_category")
 * @ORM\Entity(repositoryClass="App\Repository\RecipeCategoryRepository")
 * @ORM\HasLifecycleCallbacks
 */
class RecipeCategory
{
    /**
     * @ApiProperty(identifier=false)
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(name="r_c_id", type="integer", options={"unsigned": true})
     */
    private $id;

    /**
     * The internal primary identity key.
     *
     * @ApiProperty(identifier=true)
     * @ORM\Column(name="r_c_uuid",type="uuid", unique=true)
     */
    protected $uuid;

    /**
     * @ORM\Column(name="r_c_name", type="string", length=200)
     */
    private $name;

    /**
     * @ORM\PrePersist
     *
     * @throws Exception;
     */
    public function onPrePersist(): void
    {
        $this->uuid = Uuid::uuid4();
    }

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Recipe", mappedBy="recipeCategory", orphanRemoval=true)
     */
    private $recipes;

    public function __construct()
    {
        $this->recipes = 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;
    }

    /**
     * @return Collection|Recipe[]
     */
    public function getRecipes(): Collection
    {
        return $this->recipes;
    }



    public function getUuid()
    {
        return $this->uuid;
    }

    public function setUuid($uuid): self
    {
        $this->uuid = $uuid;

        return $this;
    }
}

<?php

namespace App\Dto;
use App\Entity\Recipe;
use Doctrine\Common\Collections\ArrayCollection;

final class RecipeCategoryOutput
{
    /**
     * @var string
     */
    public $name;

    /**
     * @var ArrayCollection<Recipe>
     */
    public $recipes;
}
<?php

namespace App\DataTransformer;

use ApiPlatform\Core\DataTransformer\DataTransformerInterface;
use App\Dto\RecipeCategoryOutput;
use App\Entity\RecipeCategory;


final class RecipeCategoryOutputDataTransformer implements DataTransformerInterface
{
    /**
     *{@inheritDoc}
     */
    public function transform($object, string $to, array $context = [])
    {
        $output = new RecipeCategoryOutput();

        $output->name = $object->getName();
        $output->recipes = $object->getRecipes();

        return $output;
    }
    /**
     * {@inheritdoc}
     */
    public function supportsTransformation($data, string $to, array $context = []): bool
    {
        return RecipeCategoryOutput::class === $to && $data instanceof RecipeCategory;
    }
}

<?php

namespace App\Entity;

use Ramsey\Uuid\Uuid;
use App\Dto\RecipeInput;
use App\Dto\RecipeOutput;
use Doctrine\ORM\Mapping as ORM;
use ApiPlatform\Core\Annotation\ApiProperty;
use ApiPlatform\Core\Annotation\ApiResource;

/**
 * @ApiResource(
 *   input=RecipeInput::class,
 *   output=RecipeOutput::class
 * )
 * @ORM\Table(name="o_recipe")
 * @ORM\Entity(repositoryClass="App\Repository\RecipeRepository")
 * @ORM\HasLifecycleCallbacks
 */
class Recipe
{
    /**
     * @ApiProperty(identifier=false)
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(name="r_id", type="integer", options={"unsigned": true})
     */
    private $id;

    /**
     * The internal primary identity key.
     * @ApiProperty(identifier=true)
     * @ORM\Column(name="r_uuid",type="uuid", unique=true)
     */
    protected $uuid;

    /**
     * @ORM\Column(name="r_name", type="string", length=200)
     */
    private $name;

    /**
     * @ORM\Column(name="r_price", type="float")
     */
    private $price;

    /**
     * @ORM\PrePersist
     *
     * @throws Exception;
     */
    public function onPrePersist(): void
    {
        $this->uuid = Uuid::uuid4();
    }



    /** 
     * @ORM\ManyToOne(targetEntity="App\Entity\RecipeCategory", inversedBy="recipes")
     * @ORM\JoinColumn(name="r_fk_recipe_category_id", referencedColumnName="r_c_id", nullable=false)
     */
    private $recipeCategory;


    public function __construct()
    {
    }

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

    public function getUuid()
    {
        return $this->uuid;
    }

    public function setUuid($uuid): self
    {
        $this->uuid = $uuid;

        return $this;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getPrice(): ?float
    {
        return $this->price;
    }

    public function setPrice(float $price): self
    {
        $this->price = $price;

        return $this;
    }


    public function getRecipeCategory(): ?RecipeCategory
    {
        return $this->recipeCategory;
    }

    public function setRecipeCategory(?RecipeCategory $recipeCategory): self
    {
        $this->recipeCategory = $recipeCategory;

        return $this;
    }
}

<?php

namespace App\Dto;

use App\Entity\RecipeCategory;

final class RecipeOutput
{
    /**
     * name of recipe
     *
     * @var string
     */
    public $name;
    /**
     * price of recipe
     *
     * @var float
     */
    public $price;
    /**
     * category of recipe
     *
     * @var RecipeCategory
     */
    public $category;
}

<?php

namespace App\DataTransformer;

use ApiPlatform\Core\DataTransformer\DataTransformerInterface;
use App\Dto\RecipeOutput;
use App\Entity\RecipeCategory;

final class RecipeOutputDataTransformer implements DataTransformerInterface
{
    /**
     *{@inheritDoc}
     */
    public function transform($object, string $to, array $context = [])
    {
        $output = new RecipeOutput();

        $output->name = $object->getName();
        $output->price = $object->getPrice();
        $output->category = $object->getRecipeCategory();

        return $output;
    }
    /**
     * {@inheritdoc}
     */
    public function supportsTransformation($data, string $to, array $context = []): bool
    {
        return RecipeOutput::class === $to && $data instanceof RecipeCategory;
    }
}

i don’t want to put RecipeCategoryOutput as a api resource. thank you in advance for helping me

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:11 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
alanpoulaincommented, Jun 3, 2020

Thank you @snoob, I didn’t see that the correct class to use was in the source.

Should be fixed by https://github.com/api-platform/core/pull/3594.

@mxmp210 documentation is far from perfect, don’t hesitate to improve it!

0reactions
d3bug-gitcommented, Jun 9, 2020

Okay coming back to old issues, Here’s the thing : When you use data transformer for multiple objects in relation you need to convert all the output to output classes. Api platform only knows types and it will expect that return type from developer when transforming, providing or serializing objects and it’s developer’s responsibility to transform such object.

So when you say you want to output Recipies with Categories both having DTO for IO. Your transformer need to instantiate relevant transformer and loop through each object of original reciepie and category, convert it into DTO itself. You just cannot mix types and pass raw object expect it to convert automatically. That works for single item only not for related collections and thus in ReciepieOutput also must transform any related DTO in this case CategoryOutput from Category entity. Follow the trail and you will find where types do not match. Make datatransformer object, convert object(s) and you are good to go.

hello @mxmp210 i try the subresource DTO fix of @alanpoulain the api-platform transform automatically multiple relations

Read more comments on GitHub >

github_iconTop Results From Across the Web

Internal server error when using GraphQL: Probably related to ...
Hi, I am trying to use GraphQL to access diabete mellitus (EFO_0000400)'s full association profile, since the webpage downloading has failed ...
Read more >
jpa entitymanager - map query result into nested dto classes
Now my question: is there any way with EntityManager that map flat query result into my nested UserDTO? In fact, I need to...
Read more >
Index (Atlassian Confluence 7.3.3 API)
Base implementation of ServiceCommand that takes care of the internal logic related to the order in which the various operations must be performed....
Read more >
https://huggingface.co/dbernsohn/roberta-php/commi...
+gin e +ix ed +Ġ Error +re po +F oreign +vi ded +andl ers +attach ment +Ġ attribute +3 ... +en ame +file...
Read more >
Technology Archives - N47
In order to make some REST request, your service needs to know the service ... Unwrapping these optional results(value and error) in more...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found