Nano Hash - криптовалюты, майнинг, программирование

Doctrine2 — прокси-объект среди обычных объектов в getResult

В моем контроллере Symfony2 у меня есть два запроса:
как в этом примере:

$object = $this->getDoctrine()->getManager()
           ->createQuery('SELECT PARTIAL o.{id,name,field1} 
                          FROM SomeBundle:SomeEntity o  
                          WHERE o.id = :objectId')
                    ->setParameter('objectId', $objectId)
                    ->getResult();



$objects = $this->getDoctrine()->getManager()
           ->createQuery('SELECT PARTIAL o.{id,name,field1, field2} 
                          FROM SomeBundle:SomeEntity o ')
                    ->getResult();

Эффект, который я получаю в коллекции $objects, представляет собой набор объектов SomeBundle:SomeEntity, за исключением того, который я получил для переменной $object, для которого я получаю объект Proxy.

Если я вывожу коллекцию $objects и для каждого элемента я хочу распечатать вывод, который включает поля: имя, поле1, поле2, я получаю null для поля2 для этого объекта. На самом деле, если я получу этот $object в любом другом контроллере, запущенном вместе с этим, field2 также будет нулевым при каждой ссылке на объект.

Например, если я хочу отображать каждый объект как:

name field1 field2

Я получаю следующий массив для $objects:

nameExample field1Example field2Example
nameExample field1Example field2Example
nameExample field1Example 
nameExample field1Example field2Example
nameExample field1Example field2Example

где третья строка — это $object.
Если я получаю поле2 в первом запросе, оно также отображается в getResult второго. Но это заставляет меня контролировать все поля, полученные для любого объекта Entity во всем запросе.

  1. Что я мог сделать не так?
  2. Как я могу избежать этого эффекта? Я все-таки хочу работать с объектами, а не с многомерными массивами (как для HYDRATE_ARRAY)
  3. Есть ли способ заставить доктрину всегда приводиться к объектам сущностей, а не к прокси-объектам?

Заранее спасибо.

19.11.2016

Ответы:


1

Это происходит потому, что Doctrine хранит внутреннюю ссылку на каждую возвращаемую сущность. Когда вы запрашиваете объект, который вы запрашивали ранее, он повторно использует предыдущий объект. Причина этого в том, что наличие двух разных копий одного и того же объекта может привести к конфликтам, если вы попытаетесь манипулировать ими обоими. Дополнительные сведения см. в разделе http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/unitofwork.html#how-doctrine-keeps-track-of-objects

Одно из решений — отсоединить объект, который вы получили первым (используя либо $em->detach($object), либо $em->clear()) перед выполнением второго запроса. Обратите внимание: любые внесенные вами изменения, которые еще не были сброшены, будут удалены.

Другой вариант — либо обновить объект с помощью $em->refresh($object) (это приведет к его полной загрузке), либо сообщить Doctrine, что необходимо обновить все объекты для второго запроса:

$query = $this->getDoctrine()->getManager()->createQuery('SELECT PARTIAL o.{id,name,field1, field2} FROM SomeBundle:SomeEntity o ');
$query->setHint(Query::HINT_REFRESH, true);
$objects = $query->getResult();

Это заставит Doctrine обновить все объекты, найденные для этого второго запроса.

06.01.2017
  • Спасибо за ответ. Ранее я рассматривал подобное решение, но эта проблема возникает также в одном примере запроса, когда вы запрашиваете сущность с ассоциацией «один ко многим», сделанной дважды для какой-либо другой сущности. В этом случае вы не можете отсоединять объекты или очищать их, так как они находятся в том же запросе. Что вы думаете об этом? 06.01.2017
  • Что именно вы имеете в виду под ассоциацией, созданной дважды? У вас есть объект A с двумя разными ассоциациями с объектом B (например, объект News с полями created_by и updated_by, которые оба указывают на объект User)? А вы их как-то грузите с PARTIAL? 06.01.2017
  • Я имел в виду описанную здесь ситуацию: github.com/doctrine/doctrine2/issues/5731, так что на самом деле я был недостаточно точен, так как эта проблема замечена с таким вариантом ассоциаций: A->B->A . 06.01.2017
  • Явная перезагрузка с использованием $em->refresh($object) должна решить эту проблему за вас, поскольку она полностью перезагрузит (все переменные указывают на) сущность. 09.01.2017
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..