Symfony 2.7 findOneBy()函数查找错误的实体

时间:2016-01-19 16:37:28

标签: symfony doctrine-orm entity arraycollection

我有一个控制器操作,该操作应该在集合中查找半重复条目,并从该实体列表中删除它们。新的不应该有ID,而现有的ID也没有,所以我运行findOneBy()一系列参数来匹配(省略ID)。

我感到困惑,并且对我得到的错误感到困惑,它找到了错误的实体!我在下面有一些相关的代码,我希望这只是一个梦想或一个愚蠢的错误,我无法在我自己的Windows开发环境中重现输出,但我的同事正在他的Mac上进行测试,并且遇到了错误,所以我继续他的机器并做了一些快速的回应,看看发生了什么。请参阅下面的代码和结果。

CODE

foreach($entity->getTechnicians() as $tech) {
  //find new addtions, see if they exist
  if (!$tech->getId()) {
    echo "Technician " . $tech->getFirstName() . " has no ID, trying to find one that does<br/>";
    $found = $em->getRepository('TechnicianBundle:Technician')->findOneBy(array(
      'firstName' => $tech->getFirstName(),
      'lastName' => $tech->getLastName(),
      'email' => $tech->getEmail(),
      'residentEngineer' => $tech->getResidentEngineer(),
      'officeNumber' => $tech->getOfficeNumber()
    ));

    //if one with an ID already exists
    if ($found) {
      echo "found technician " . $found->getFirstName() . " that already has id " . $found->getId() . "<br/>";
     ...

输出

  

技术人员没有身份证,试图找到一张身份证明     找到技术员 khjvuov 已经有id 7

2 个答案:

答案 0 :(得分:2)

可能它不是findOneBy()问题。

如果没有添加/删除调用它可以工作,它可能是由修改的 ArrayCollection 的当前指针引起的,所以当调用$ tech-&gt; getFirstName()时它实际指向另一个条目。

您可以尝试按照以下方式迭代您的收藏:

$iterator = $entity->getTechnicians()->getIterator();
while ($iterator->valid()) {
  $tech = $iterator->current();

  ... $entity->addTechnician()/$entity->removeTechnician()

  $iterator->next();
}

它将创建新的ArrayIterator对象,因此您可以修改底层对象,保留ArrayCollection的内部指针。

如果您运行PHP7(reference - 注意框)

,这可能已过时

答案 1 :(得分:0)

最终,findOneBy()方法使用load() method of the Doctrine ORM

在文档中,参数$criteria被描述为:

@param array $criteria The criteria by which to load the entity.

你可能应该深入研究Doctrine API以确保,但是你在作为参数传递的数组中很可能只有第一个 key =&gt;值对被考虑在内(在您的示例中,'firstName'=&gt; $ tech-&gt; getFirstName())。

如果是这种情况,您可能需要在实体存储库中添加自己的自定义方法,该方法允许您使用更高级的语句查询数据库(使用OR/AND或{{1}例如,在SQL中。)