Symfony 2.7 findOneBy() 函数发现了错误的实体
Symfony 2.7 findOneBy() Function Finds the Wrong Entity
我有一个控制器操作,它应该在集合中寻找半重复的条目,并将它们从该实体的列表中删除。新的应该还没有 ID,而现有的应该有,所以我 运行 findOneBy()
有一组要匹配的参数(省略 ID)。
我对我遇到的错误感到困惑和深感困扰,它找到了错误的实体!我在下面有一些相关代码,我希望这只是一个梦或一个愚蠢的错误,我无法在自己的 windows 开发环境中重现输出,但我的同事正在他的 mac,并且出现错误,所以我继续他的 machine 并快速回应以查看发生了什么。请参阅下面的代码和结果。
代码
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/>";
...
输出
Technician Four has no ID, trying to find one that does
found technician khjvuov that already has id 7
最终,findOneBy()
方法使用 load()
method of the Doctrine ORM。
在文档中,参数$criteria
是这样描述的:
@param array $criteria The criteria by which to load the entity.
您可能应该更深入地研究 Doctrine API 以确保确定,但很有可能在您作为参数传递的数组中,只有第一个 key => value 对被考虑在内(在您的示例中,'firstName' => $tech->getFirstName())。
如果是这种情况,您可能需要在您的实体存储库中添加您自己的自定义方法,该方法允许您使用更高级的语句(使用 OR/AND
或 [=例如 SQL 中的 15=]。
可能不是 findOneBy() 的问题。
如果没有 add/remove 调用它会起作用,这可能是由于修改了 ArrayCollection 的当前指针造成的,所以当 $tech->getFirstName() 被调用时它实际上指向到另一个条目。
您可以尝试像这样迭代您的 collection:
$iterator = $entity->getTechnicians()->getIterator();
while ($iterator->valid()) {
$tech = $iterator->current();
... $entity->addTechnician()/$entity->removeTechnician()
$iterator->next();
}
它将创建新的 ArrayIterator object,因此您可以修改基础 object 保留 ArrayCollection 的内部指针。
如果您是 运行 PHP7(reference - 注释框)
,这可能已过时
我有一个控制器操作,它应该在集合中寻找半重复的条目,并将它们从该实体的列表中删除。新的应该还没有 ID,而现有的应该有,所以我 运行 findOneBy()
有一组要匹配的参数(省略 ID)。
我对我遇到的错误感到困惑和深感困扰,它找到了错误的实体!我在下面有一些相关代码,我希望这只是一个梦或一个愚蠢的错误,我无法在自己的 windows 开发环境中重现输出,但我的同事正在他的 mac,并且出现错误,所以我继续他的 machine 并快速回应以查看发生了什么。请参阅下面的代码和结果。
代码
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/>";
...
输出
Technician Four has no ID, trying to find one that does
found technician khjvuov that already has id 7
最终,findOneBy()
方法使用 load()
method of the Doctrine ORM。
在文档中,参数$criteria
是这样描述的:
@param array $criteria The criteria by which to load the entity.
您可能应该更深入地研究 Doctrine API 以确保确定,但很有可能在您作为参数传递的数组中,只有第一个 key => value 对被考虑在内(在您的示例中,'firstName' => $tech->getFirstName())。
如果是这种情况,您可能需要在您的实体存储库中添加您自己的自定义方法,该方法允许您使用更高级的语句(使用 OR/AND
或 [=例如 SQL 中的 15=]。
可能不是 findOneBy() 的问题。
如果没有 add/remove 调用它会起作用,这可能是由于修改了 ArrayCollection 的当前指针造成的,所以当 $tech->getFirstName() 被调用时它实际上指向到另一个条目。
您可以尝试像这样迭代您的 collection:
$iterator = $entity->getTechnicians()->getIterator();
while ($iterator->valid()) {
$tech = $iterator->current();
... $entity->addTechnician()/$entity->removeTechnician()
$iterator->next();
}
它将创建新的 ArrayIterator object,因此您可以修改基础 object 保留 ArrayCollection 的内部指针。
如果您是 运行 PHP7(reference - 注释框)
,这可能已过时