Core: The total number of joined relations has exceeded the specified maximum

Created on 30 Apr 2018  路  6Comments  路  Source: api-platform/core

I have two entities, one representing a Todo

// Todo entity
/**
 * @ORM\Table(name="coo_app_todos")
 * @ORM\Entity()
 * @ApiResource(
 *     attributes={
 *        "normalization_context"={"groups"={"todo"}}
 *     },
 *     itemOperations={
 *          "get",
 *          "put"={"normalization_context"={"groups"={"put"}}}
 *     }
 * )
 */
class Todo
{
    use TimestampableEntity;

    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * @Groups({"todoList", "todo"})
     */
    private $id;

    /**
     * @var TodoList
     *
     * @ORM\ManyToOne(targetEntity="App\Entity\TodoList", inversedBy="todos")
     * @ORM\JoinColumn(name="toto_list", referencedColumnName="id")
     * @Groups({"todo", "put"})
     */
    private $todoList;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     * @Groups({"todoList", "todo", "put"})
     */
    private $name;

    ...

}

and one representing a TodoList:

// TodoList
/**
 * @ORM\Table(name="coo_app_todo_lists")
 * @ORM\Entity()
 *
 * This makes possible to return also the todos associated to the fetched TodoList.
 * @ApiResource(attributes={
 *     "normalization_context"={"groups"={"todoList"}}
 * })
 */
class TodoList
{

    ...

    /**
     * @var Collection
     *
     * @ORM\OneToMany(targetEntity="App\Entity\Todo", mappedBy="todoList")
     * @ORM\OrderBy({"opened" = "DESC"})
     * @ApiSubresource()
     * @Groups("todoList")
     */
    private $todos;

    ...

}

A Todo is obviously associated to a TodoList and I need that when I fetch a Todo, I get also some details of the TodoList.

But this configuration doesn't permit me to create new Todos as I receive this error:

The total number of joined relations has exceeded the specified maximum. Raise the limit if necessary, or use the \"max_depth\" option of the Symfony serializer.

I'm trying with a payload like this:

{
    "todoList": "/api/todo_lists/1",
    "name": "Vediamo che succede"
}

Nothing complex: just the name of the Todo and the TodoList in which it is.

I've tried to add "put"={"normalization_context"={"groups"={"put"}}} to the itemOperations but this didn't solved my problem.

Any ideas of how I can solve this problem?

I need that the TodoList is embedded in the response I receive for a single Todo and, obviously, I want to be able to also create new Todos.

Thank you!

PS

The api documentation is telling me that the payload should be something like this:

{
  "todoList": {
    "account": "string",
    "name": "string",
    "createdAt": "2018-04-30T14:24:44.463Z",
    "updatedAt": "2018-04-30T14:24:44.463Z"
  },
  "name": "string",
  "description": "string",
  "opened": true,
  "createdAt": "2018-04-30T14:24:44.463Z",
  "updatedAt": "2018-04-30T14:24:44.463Z"
}

So I think that there is something wrong with the configuration of the embedding...

question

Most helpful comment

There's a relation joining recursivity.
Two solutions:

  1. Disable eager loading ( https://api-platform.com/docs/core/performance#eager-loading ) https://github.com/api-platform/core/issues/876#issuecomment-266053664
  2. Use @MaxDepth with enable_max_depth: true
@ApiResource(attributes={"normalization_context": {"groups"={"todolist"}, "enable_max_depth"=true}})

All 6 comments

There's a relation joining recursivity.
Two solutions:

  1. Disable eager loading ( https://api-platform.com/docs/core/performance#eager-loading ) https://github.com/api-platform/core/issues/876#issuecomment-266053664
  2. Use @MaxDepth with enable_max_depth: true
@ApiResource(attributes={"normalization_context": {"groups"={"todolist"}, "enable_max_depth"=true}})

@soyuka , thank you for your fast reply!

Can you provide me with an example, please?

I've tried to use enable_max_depth and the annotation @MaxDepth as shown in the Symfony's Serializer doc, but the problem isn't solved, so maybe I'm continuing to configure it wrong...

I've enabled the annotations for Serializer in framework and set the @MaxDepth(1) annotation on properties Todo::todoList and TodoList::todos but this seems to not solve the problem.

Ok, I'm doing other tests, but without success.

TEST 1: Disable eagerLoading on a ApiResource basis

First, I tried to disable the eagerLoading this way:

// Todo entity
/**
 * @ORM\Table(name="coo_app_todos")
 * @ORM\Entity()
 * @ApiResource(attributes={
 *     "fetchEager": false,
 *     "normalization_context"={"groups"={"todo"}}
 * })
 */
class Todo
{
    ...
}

and

// TodoList entity
/**
 * @ORM\Table(name="coo_app_todo_lists")
 * @ORM\Entity()
 *
 * This makes possible to return also the todos associated to the fetched TodoList.
 * @ApiResource(attributes={
 *     "fetchEager": false,
 *     "normalization_context"={"groups"={"todoList"}}
 * })
 */
class TodoList
{
    ...
}

FAILED: The error is still there.

TEST 2: Disable eager loading for all resources

As suggested by @dunglas in https://github.com/api-platform/core/issues/876#issuecomment-266053664 and described in the documentation here, I added this to my config/packages/api_platform.yaml config file:

api_platform:
    mapping:
        paths: ['%kernel.project_dir%/src/Entity']
    eager_loading:
      force_eager: false

SOLVED: This solved the problem, but opened another one.

THE CURRENT PROBLEM

Using force_eager: false now I can create new todos but I suspect this will impact performances.

So, my question is: is this behavior intended? Is it possible that if one uses @Groups (s)he incurs in those problems?

TEST 3: force_eager at @ApiResource level

As suggested by @soyuka in https://github.com/api-platform/api-platform/issues/187#issuecomment-263201400 (and also in a previous comment in this issue too ), I did this:

// TodoList entity
/**
 * @ORM\Table(name="coo_app_todo_lists")
 * @ORM\Entity()
 *
 * This makes possible to return also the todos associated to the fetched TodoList.
 * @ApiResource(attributes={
 *     "force_eager"=false, // Instead of "fetchEager": false,
 *     "normalization_context"={"groups"={"todoList"}}
 * })
 */
class TodoList
{
    ...
}

This worked too!

CONCLUSIONS

So, my suggestion is to create a troubleshooting section in the documentation where this issue is addressed and the solutions I tried here are better described: I spent a lot of time figuring out how to solve the issue!

Anyway, thank you @soyuka and @dunglas for the suggestione you leave in the issues: reading with more calm and deeper, I was able to finally solve the issue!

How did you solve this issue? can you give me idea? :)

work for me 馃憤
`@ApiResource(attributes={

  • "force_eager"=false,
  • "normalization_context"={"groups"={"readCO"},"enable_max_depth"=true},
  • "denormalization_context"={"groups"={"writeCO"},"enable_max_depth"=true}



  • })`

work without "force_eager"=false TOO

Was this page helpful?
0 / 5 - 0 ratings