首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >忽略规则中缺失的实体

忽略规则中缺失的实体
EN

Stack Overflow用户
提问于 2015-09-22 04:42:36
回答 3查看 1.8K关注 0票数 2

我们正在将一个应用程序移植到Symfony2上,并且目前使用的是doctrine。我们在数据库中有一堆坏的外键,并且在没有运行到“实体找不到”异常的情况下进行关系映射变得越来越困难。这是清理数据库的路线图,但不幸的是,这不是我们现在可以解决的问题。如果没有找到正确的实体,有没有办法让它只返回null?

如果我有以下关系映射:

代码语言:javascript
运行
复制
    User:
      type: entity
      table: user
      id:
        userID:
          type: integer
          generator:
            strategy: NONE
      fields:
        contactName:
          type: string
          length: 255
          nullable: false
        contactPhone:
          type: string
          length: 255
          nullable: false
        companyName:
          type: string
          length: 255
          nullable: false
        username:
          type: string
          length: 255
          nullable: false
        password:
          type: string
          length: 255
          nullable: false
        email:
          type: string
          length: 255
          nullable: false
      manyToOne:
          address:
            targetEntity: Address
            joinColumn:
              name: addressID
              referencedColumnName: addressID
              nullable: true
              default: null



    -----------------------------------------------------

    Address:
      type: entity
      table: address
      id:
        addressID:
          type: integer
          generator:
            strategy: AUTO
      fields:
        street:
          type: string
          length: 255
          nullable: false
        street2:
          type: string
          length: 255
          nullable: false
        city:
          type: string
          length: 255
          nullable: false
        state:
          type: string
          length: 32
          nullable: false
        zip:
          type: string
          length: 10
          nullable: false
        country:
          type: string
          length: 40
          nullable: false

似乎如果user表中的addressID值不正确,我会得到一个"Entity was not found“。通过序列化程序发送它时发生异常。

EN

回答 3

Stack Overflow用户

发布于 2015-09-22 04:57:10

是的,这是完全有可能的,但我很难告诉你怎么做,因为你没有提供任何例子。你能给出一些现有的代码示例,这样我就可以给你一些建议了吗?

顺便说一句,您可以像这样在存储库中进行查询:

代码语言:javascript
运行
复制
$qb = $this->entityManager->createQueryBuilder();
$qb->select('e')
    ->from('MyBundle:Entity', 'e')
    ->where($qb->expr()->eq('e.id', ':id'))
    ->setParameter('id', 1)
    ->setMaxResults(1);

$result = $qb->getQuery()->getOneOrNullResult();

如果未找到实体,则结果将包含null。但我认为大多数情况下find*方法会返回null。检查Doctrine2中的Repository类。如果需要,您还可以扩展Doctrine的存储库并覆盖方法,以防抛出异常。您可以捕获它并返回null、空数组或任何手工创建的对象...等。

如果您正在进行任何连接,如果您不确定数据是否存在,也可以考虑使用left join。此外,在代码中访问引用的对象时,例如,如果您有:

代码语言:javascript
运行
复制
$user->getProfile();

并且存在返回null的危险,请在返回对象之前检查方法本身,如下所示:

代码语言:javascript
运行
复制
public function getProfile()
{
    if ($this->profile === null) {
        return new DummyProfile();
    }

    return $this->profile;
}

其中DummyProfile可以扩展您的原始配置文件对象,它可以像一个模拟对象,返回一些默认值。您还可以将这个虚拟对象保存在一个属性中,并在下次返回它,这样它就不会一直被实例化(单例模式)。这就是你保护你的代码的方式,这样你就不会在null上调用方法,这会导致php错误。

希望这能给你一个如何继续的想法...:)

票数 0
EN

Stack Overflow用户

发布于 2016-07-28 18:46:49

啊,这也是我们经常看到的皮塔饼。如果你已经禁用了延迟加载,那么Doctrine可能会加载和水合所有链接的实体。但我猜当你尝试在Symfony中渲染一个模板/表单时,它是打开的,而是消亡的。

在延迟加载打开的情况下,加载实体时不会出现错误,但是,如果您随后尝试访问相关实体的属性(这将导致Doctrine加载它),或者在symfony表单中呈现实体,并且表单上的字段与外部表的属性相关,则会出现错误。

不幸的是,没有简单的方法来阻止或捕捉这种情况。我的建议是手动检查数据中是否有坏的外键并清理数据,Doctrine的懒加载对于坏数据尤其不可原谅,而Symfony只会让情况变得更糟,如果它遇到一个不可靠的链接,就会报错500。

票数 0
EN

Stack Overflow用户

发布于 2018-07-18 23:45:42

我刚刚遇到了同样的问题,在寻找解决方案时发现了这个问题……但我没找到。下面是我所做的(使用注释):

  1. 让这种关系变得懒惰:

/** * @var Resource ** @ORM\JoinColumn(name="ResourceID",referencedColumnName="ResourceID") *@ORM\ use (targetEntity=“Resource”,fetch="LAZY") */ private $resource;private $_resource_is_valid =null;

  • 修改getter并始终使用它--甚至在类内部:

/** *返回关联的资源,考虑到错误的引用。* @return Resource|null */公共函数getResource() { if (is_null( $this->_resource_is_valid )) { try { //如果($this->resource && $this->resource->getID(){$this->_resource_is_valid=true,我们需要调用触发延迟加载的方法;}} catch (\Doctrine\ORM\EntityNotFoundException $enf) { $this->_ resource _is_valid = false;//考虑创建一个新的资源对象。}} if ($this->_resource_is_valid) { return $this->resource;} return null;}

这种方法允许Doctrine部分水合实体,并允许您在您拥有更多控制的区域中捕获不良关系。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32704216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档