symfony 3.4 - ManyToOne не может получить доступ к данным сущности - PullRequest
0 голосов
/ 30 ноября 2018

У меня есть объект вызова категории, другой продукт вызова и один в середине под названием CategoryProduct.

  • У меня есть отношение OneToMany между Category и CategoryProduct: @ORM\OneToMany(targetEntity="CategoryProduct", mappedBy="Catego", fetch="EAGER") с inversedBy в CategoryProductкласс (на $ catego).
  • У меня есть отношение OneToOne между CategoryProduct и Product: @ORM\OneToOne(targetEntity="Product", inversedBy="Category") с inversedBy в классе Product (в категории $).

внутри моего CategoryController у меня есть функция, подобная этой:

public function getCategoryAction(Request $request)
{
    $category = $this->get('doctrine.orm.entity_manager')
                 ->getRepository('AppBundle:Category')
                 ->findAll();
    return new JsonResponse($category);
}

В результате возврата получается коллекция сущности Category, но продукт "sub entity" Product пуст.Когда я проверяю токен на предмет debbug в Symfony, я проверяю раздел Doctrine, и запрос работает отлично, данные загружаются, но их просто нет в моем возвращении.Я могу получить доступ к данным, используя $category->getProduct() (он дает мне коллекцию Ссылка продукта на категорию, как я хочу), но мой подкласс Продукта по-прежнему пуст.Кто-нибудь знает почему?

Спасибо за вашу помощь.

Ответы [ 3 ]

0 голосов
/ 10 декабря 2018

Ниже моего обновления контроллера с помощью метода, который вы мне дали.

public function getTariffsAction(Request $request, SerializerInterface $serializer) 
{
    $category = new Category();
    $category = $this->get('doctrine.orm.entity_manager')
            ->getRepository('AppBundle:Category')
            ->findAll();
    $categoryJson = $serializer->serialize($category , 'json', ['groups' => ['tariffs'] ]);
    return $this->json($categoryJson);
}

и когда я выкидываю категорию $, я получаю то, что не могу вставить, потому что это слишком много.С почтальоном это сильно мешает работе моего компьютера (один из экранов отключается), после этого мне приходится перезагружаться

0 голосов
/ 20 декабря 2018

Проблема решена, вы были абсолютно правы, это была круговая ссылка, и я решил ее с группами, как вы сказали.(Я использовал FOSRestBundle для групп проще, чем нативные методы Symfony)

0 голосов
/ 01 декабря 2018

Принимая вещи с самого начала, ваша текущая проблема - это типичная вещь для гидратации Доктрины.

По умолчанию Doctrine загружает отношения лениво, это означает, что изначально Doctrine предоставляет прокси-коллекцию, которая не содержит в себе никакого элемента, и загружает фактические элементы только тогда, когда к ним обращаются каким-либо образом (например, при использовании геттера).как getProduct ()).Вот почему ваша коллекция Product кажется пустой.

Вы можете легко изменить это, установив для атрибута fetch в вашей ассоциации значение EAGER:

// inside Category class
/**
 * @ManyToOne(targetEntity="Product", fetch="EAGER")
 */
 private $products;

Однако в конечном итоге ваш код не заработает, потому что когда выпытаясь json_encode объекта с закрытыми свойствами, в результате вы получите только пустой json.Решением вашей проблемы является использование нестандартного способа сериализации вашего объекта.Самое простое (и, вероятно, лучшее) решение - использовать Symfony Serializer Component.НО вы должны знать, что простое использование $serializer->serialize($category, 'json'); вызовет исключение циклической ссылки.Это будет вызвано тем, что (как я полагаю) вы также держите в своем классе Product ссылку на Категорию, например, такую:

// inside Product class
/**
 * @OneToMany(targetEntity="Category")
 */
private $category;

Как вы можете себе представить, Symfony попытается сериализовать категорию, в которой много продуктов.с категорией, с множеством продуктов ... это круговая ссылка.

Чтобы обойти эту проблему, вы должны использовать такие группы сериализации:

// inside your controller, supposing you are using autowiring to inject services:

use Symfony\Component\Serializer\SerializerInterface;

public function getTariffsAction(Request $request, SerializerInterface $serializer)
{
    $category = $this->get('doctrine.orm.entity_manager')
             ->getRepository('AppBundle:Category')
             ->findAll();

    $categoryJson = $serializer->serialize($category, 'json', ['groups' => ['tariffs'] ]);

    return $this->json($categoryJson);
}

Затем явно настроить атрибутыиз ваших объектов, вы хотели бы проникнуть внутрь ваших сущностей следующим образом:

// Category.php
use Symfony\Component\Serializer\Annotation\Groups;
...
/**
 * @ORM\Id
 * @Groups({"tariffs"})
 */
protected $id;

/**
 * @ORM\Column(type="string")
 * @Groups({"tariffs"})
 */
protected $name;

/**
 * @ORM\ManyToOne(targetEntity="Product")
 * @Groups({"tariffs"})
 */
private $product;

// any other attribute you want to include

И, наконец, в вашем Product.php:

Product.php

/**
 * @ORM\Id
 * @Groups({"tariffs"})
 */
protected $id;

/**
 * @ORM\Column(type="string")
 * @Groups({"tariffs"})
 */
protected $productName;

// do not include the reference to the category to avoid circular reference
/**
 * @OneToMany(targetEntity="Category")
 */
private $category;

. Вы можете найти больше информации о компоненте Serializer игруппы сериализации в документации .

...