【问题标题】:Doctrine return null in place of EntityNotFoundException教义返回 null 代替 EntityNotFoundException
【发布时间】:2019-01-24 09:02:14
【问题描述】:

我在我的数据库中破坏了 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>

以下是预期结果示例,其中点击作为访问者 ID,但访问者记录不存在该 ID。在这种情况下,我宁愿不必将逻辑包装在 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 捆绑包 - 您在项目中使用它吗?
  • 对不起,我不是。发帖后我才意识到自己的错误。
  • 好吧,只是想澄清一下。我认为没有办法在实体管理器或实体级别实现这一目标。 EntityNotFoundException 是从 Doctrine 的代理方法中抛出的,它们似乎不支持任何事件侦听器或自定义。您需要将 try/catch 块添加到每个 getXX 关系方法。
  • 请添加实体的代码。至少部分有关系

标签: php doctrine-orm entity


【解决方案1】:

EntityNotFoundException 从 Doctrine 的代理中抛出。所以你可以使用EAGER加载方法来摆脱代理,得到NULL而不是异常。

【讨论】:

    【解决方案2】:

    这是我基于iainn制作的comment采取的策略。

    <?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;
        }
    }
    

    我确信不建议您的实体直接与代理交互。但我更喜欢在实体上调用已知方法(这也会产生加载它的效果),因为此代码的意图对于可能阅读它的下一个开发人员来说更清楚。

    我不确定像这样与代理交互是否有任何副作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-03
      • 2018-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-08
      相关资源
      最近更新 更多