一组实体不会更新(Symfony2 & Doctrine)



我对此代码有问题:

$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成员的引用,而是它们的复制。然后,当您再次将新值分配给实体时,对象是新的,并且学说现在知道这些实体很脏。

最新更新