我对此代码有疑问:
$elements = $em
->getRepository('AppBundle:MyElementsEntity')
->findByLinkType($linkType); // This returns SEVEN elements
foreach ($elements as $e) {
$beginDate = $e->getBeginDate();
$beginDate->setTime($begin->format('H'), $begin->format('i'));
$endDate = $e->getEndDate();
$endDate->setTime($end->format('H'), $end->format('i'));
$e->setEndDate($endDate);
$e->setBeginDate($beginDate);
$em->persist($e);
$em->flush();
}
如您所见,它从数据库中获取一些元素,从beginDate和endDate字段更改时间($ begin和$ end是DateTime对象),并尝试更新数据库。
代码不会抛出任何异常,但它不起作用。当我查看Symfony2的日志(app / logs / dev.log)时,会有SQL语句来获取数据,更改会话等,但是没有任何更新语句。
我还有另一个功能,每次只更新一个元素,这是正常的。
我做错了什么?为什么我可以批量更新以前选择的元素?我错过了一些重要的东西?
**更新**
我已经对代码进行了一些修改,但它仍然没有将实体更新到数据库中:
$em->persist($e)
来电。$em->flush()
电话移至foreach
圈外。beginTransaction()
,commit()
和rollback()
来电)但问题仍然存在:Doctrine没有向服务器发送任何UPDATE语句(仅供参考,是Oracle 11g)。
答案 0 :(得分:0)
你对循环的意图是什么?我不接缝做任何事情......如果实体没有改变(脏),Doctrine将不会执行更新查询。
$begin = $e->getBeginDate();
// $begin = 2015-05-18 14:02:00
// $begin->format('H') // will return 14
// $begin->format('i') // will return 02
$begin->setTime($begin->format('H'), $begin->format('i'));
// $begin is still 2015-05-18 14:02:00
为什么你的循环没有做任何事情:
{{1}}
答案 1 :(得分:0)
感谢所有人的帮助。最后,我发现了问题。
问题在于Doctrine查看实体是否脏的方式。他只查找标量字段(字符串,数字等)中的更改,但不查找作为对象的字段(另一个实体, DateTime对象等)。
在上面的代码片段中,我只修改了DateTime对象($e->beginDate
和$e->endDate
)的内容,但没有创建新对象。这样,Doctrine没有注意到实体的变化。避免这种情况的解决方案非常简单:
foreach ($elements as $e) {
$beginDate = clone $e->getBeginDate();
$beginDate->setTime($begin->format('H'), $begin->format('i'));
$endDate = clone $e->getEndDate();
$endDate->setTime($end->format('H'), $end->format('i'));
$e->setEndDate($endDate);
$e->setBeginDate($beginDate);
$em->flush();
}
初始化clone
和$beginDate
临时变量时请注意$endDate
关键字:它们不是对$e->beginDate
和$e->endDate
成员的引用,而是副本他们然后,当您再次将新值分配给实体时,对象是新的,并且Doctrine现在知道这些实体是脏的。