忽略教义中缺少的实体

时间:2015-09-21 20:42:36

标签: php symfony doctrine-orm

我们正在将应用程序移植到Symfony2,目前正在使用doctrine ORM。我们在数据库中有一堆坏的外键,并且越来越难以进行关系映射而不会遇到“未找到实体”#34;例外。它是清理数据库的路线图,但不幸的是,我们现在无法解决这个问题。有没有什么方法可以让它只是返回null如果它找不到合适的实体?

如果我有以下关系映射:

    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

似乎如果用户表中的addressID存在错误值,我将得到"未找到实体。"通过串行器发送时的异常。

3 个答案:

答案 0 :(得分:0)

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

您是否在存储库中进行查询:

$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,空数组或任何手工制作的对象......等等。

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

$user->getProfile();

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

public function getProfile()
{
    if ($this->profile === null) {
        return new DummyProfile();
    }

    return $this->profile;
}

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

希望能让你知道如何继续... :)

答案 1 :(得分:0)

啊,这是我们经常看到的PITA。如果你已经禁用延迟加载,那么Doc​​trine可以加载&为当时所有相关实体提供保湿。但是,当你尝试在Symfony中渲染模板/表单时,我猜它已经开启并且它正在死亡。

启用Lazy Loading时,加载实体时不会出现错误,但是如果您尝试访问相关实体的属性(这将导致Doctrine加载它)或渲染,您将收到错误symfony表单中的实体和表单上的字段与外表的属性相关。

不幸的是,没有简单的方法来阻止或抓住这个。我的建议是手动检查数据是否存在错误的外键并清理数据,Doctrine的延迟加载对于坏数据尤其不可原谅,而Symfony只是通过在遇到duff链接时使用Error 500来加剧这种情况。 / p>

答案 2 :(得分:0)

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

  1. 使关系变得懒惰:

    "//*[contains(@id,'itsAnExampleBoi')]/div[1]/div[2]"
    
  2. 修改吸气剂并始终使用它-即使在类内部也是如此:

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

这种方法允许Doctrine对实体进行部分水合,并使您可以在控制力更强的区域捕获不良关系。