我对此代码有问题:
$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();
}
如您所见,它从数据库中获取了一些元素,更改了从开始和端的字段($ begin and $ end and $ end是dateTime对象),并尝试更新数据库。
代码不会引发任何异常,但行不通。当我查看symfony2的日志(app/logs/dev.log)时,有SQL语句以获取数据,更改会话等,但是没有任何更新语句。
我还有另一个功能,每次都只能更新一个元素,而且工作正常。
我在做错什么?为什么我可以批量讨论以前的选定元素?我缺少重要的东西?
**更新**
我已经对代码进行了一些修改,但它仍然没有将实体更新到数据库:
- 我已经删除了
$em->persist($e)
调用。 - 我已经将
$em->flush()
调用移至foreach
循环外部。 - 我已经删除了交易代码(
beginTransaction()
,commit()
和rollback()
调用)
但是问题仍然相同:学说没有向服务器发送任何更新语句(FYI,是Oracle 11G)。
循环您的意图是什么?我不接缝做任何事情...如果没有更改实体,学说将不会执行更新查询(脏)。
$elements = $em
->getRepository('AppBundle:MyElementsEntity')
->findByLinkType($linkType); // This returns SEVEN elements
foreach ($elements as $e) {
// $beginDate is a DateTime
$beginDate = $e->getBeginDate();
$beginDate->setTime(8, 15);
$endDate = $e->getEndDate();
$endDate->setTime(9, 39);
}
$em->flush();
为什么您的循环不做任何事情:
$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
感谢所有人的帮助。最后,我发现了问题。
问题在于学说的外观是否肮脏。他仅在标量字段(字符串,数字等)中寻找更改,而不是在对象(另一个实体, dateTime对象等)的字段中寻找更改。
在上面的片段中,代码I仅修改DateTime对象的内容($e->beginDate
和$e->endDate
),而没有创建新对象。这样,学说就不会注意到实体发生变化的地方。避免这种情况的解决方案确实很容易:
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();
}
初始化$beginDate
和$endDate
临时变量时请注意clone
关键字:它们不是对$e->beginDate
和$e->endDate
成员的引用,而是它们的复制。然后,当您再次将新值分配给实体时,对象是新的,并且学说现在知道这些实体很脏。