Доктрина возвращает null вместо EntityNotFoundException

Я сломал FK в своей базе данных, и если я загружу объект и запрошу связанный объект, Doctrine выдаст \Doctrine\ORM\EntityNotFoundException.

Для рассматриваемой сущности я бы предпочел, чтобы при нарушении FK она возвращала NULL, а не генерировала исключение. Это связано с тем, что исключение возникает в шаблоне Twig, и я бы предпочел, чтобы Twig не обрабатывал исключение в этом случае.

Ниже приведен пример конфигурации.

<?xml version = "1.0" encoding = "utf-8"?>
<doctrine-mapping xmlns = "http://doctrine-project.org/schemas/orm/doctrine-mapping"
                  xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation = "http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
    <entity name = "Foo\Click" table = "clicks">
        <id name = "id" type = "bigint" column = "click_id">
            <generator strategy = "IDENTITY"/>
        </id>
        <!-- .. -->
        <many-to-one field = "visitor" target-entity = "Foo\Visitor" fetch = "LAZY">
            <join-columns>
                <join-column name = "visitor_id" referenced-column-name = "visitor_id"/>
            </join-columns>
        </many-to-one>
    </entity>

    <entity name = "Foo\Visitor" table = "visitors" read-only = "true">
        <id name = "visitorId" type = "integer" column = "visitor_id">
            <generator strategy = "IDENTITY"/>
        </id>
        <!-- ... -->
        <one-to-one field = "firstClick" target-entity = "Foo\Click" fetch = "LAZY">
            <join-columns>
                <join-column name = "click_id" referenced-column-name = "click_id"/>
            </join-columns>
        </one-to-one>
    </entity>
</doctrine-mapping>

Ниже приведен пример ожидаемых результатов, когда щелчок используется в качестве идентификатора посетителя, но запись посетителя с этим идентификатором не существует. В этом случае я бы предпочел не заключать логику в Try / Catch и вместо этого иметь Click::getVisitor() return null;

<?php
$clickOne = $entityManager()->find(Foo\Click::class, 1);
$v = $clickOne->getVisitor();

if ($v !== null) {
    echo $v->getId(); // may throw Doctrine\ORM\EntityNotFoundException
}

Есть ли для этого стратегия в Doctrine?


Обновлять: Добавлен пример конфигурации и кода, и теперь я понимаю, почему это невозможно с простой конфигурацией Doctrine.

Этот PR предназначен для комплекта jms/serializer - вы используете его в своем проекте?

iainn 17.08.2018 12:28

Извини, я нет. Я осознал свою ошибку после публикации.

Courtney Miles 17.08.2018 12:32

Хорошо, просто хотел уточнить. Я не думаю, что есть способ добиться этого на уровне entitymanager или entity. EntityNotFoundException выбрасывается из методов прокси Doctrine, которые, похоже, не поддерживают какие-либо прослушиватели событий или настройку. Вам нужно будет добавить блоки try/catch к каждому методу взаимосвязи getXX.

iainn 17.08.2018 12:38

пожалуйста, добавьте код сущностей. по крайней мере, расстается с отношениями

Denis Alimov 17.08.2018 15:00

Аналогичный вопрос существует на Twig и Symfony2 - объект не найден

Courtney Miles 20.08.2018 05:12
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
3
5
1 130
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

EntityNotFoundException создается прокси Doctrine. Таким образом, вы можете использовать метод загрузки EAGER, чтобы избавиться от прокси и получить NULL вместо исключения.

Ответ принят как подходящий

Это стратегия, которую я принял на основе комментарий, созданного iainn.

<?php
class Parent
{
    protected $child;

    public function getChild()
    {
        if ($this->child instance of \Doctrine\ORM\Proxy\Proxy) {
            try {
                $this->child->__load();
            } catch (\Doctrine\ORM\EntityNotFoundException $e) {
                $this->child = null
            }
        }

        return $this->child;
    }
}

Я уверен, что вашим организациям не рекомендуется напрямую взаимодействовать с прокси. Но я предпочел это вызову известного метода для объекта (который также будет иметь эффект его загрузки), потому что цель этого кода более ясна для следующего разработчика, который мог бы его прочитать.

Я не уверен, есть ли какие-либо побочные эффекты при таком взаимодействии с прокси.

Другие вопросы по теме