【问题标题】:Symfony2 - Updating an entity in a one-to-one relationshipSymfony2 - 在一对一关系中更新实体
【发布时间】:2015-01-01 22:52:26
【问题描述】:

我正在尝试更新我的 SingleTask 实体,但不接受任何更改。我的 Event 和 SingleTask 的关系是双向的一对一关系。

我的事件实体的相关部分是:

class Event
{
   // properties

   /**
    * @OneToOne(targetEntity="SingleTask", mappedBy="event", cascade={"persist", "remove"})
    */
   private $singletask;

   public function setSingleTask(SingleTask $singletask)
   {
      $this->singletask = $singletask;
      $singletask->setEvent($this);
   }

   public function getSingleTask()
   {
      return $this->singletask;
   }
}

我的 SingleTask 实体的相关部分是:

/**
 * @Entity
 */
class SingleTask
{
   /**
    * @Column(type="datetime", nullable=true)
    */
   private $lastRun;

   /**
     * @OneToOne(targetEntity="Event", inversedBy="singletask")
     * @JoinColumn(name="event_id", referencedColumnName="id", nullable=true)
     **/
   private $event;

   public function setLastRun(\DateTime $lastRun = null)
   {
      $this->lastrun = $lastRun;
   }
}

在单独的命令文件中:

$eventRepo = $this->em->getRepository('HeyRemy\HeyRemyBundle\Entity\Event');
$events = $eventRepo->findAll();

foreach ($events as $event)
{
   $singletask = $event->getSingleTask();

   if ($singletask != null)
   {
      $singletask->setLastRun(new \DateTime);
      $event->setSingleTask($singletask);

      $this->em->flush();
   }
}

不幸的是,SingleTask 上的 lastRun 属性永远不会在数据库中更新。什么不正确?

编辑:我如何创建事件的代码示例:

$event = new Event();
$userRepo = $this->em->getRepository('HeyRemyBundle:User');
$user = $userRepo->find($user_id);
$event->setUser($user);

$this->em->persist($event);
$this->em->flush();

$event_id = $event->getId();

// other code which uses $event_id (SingleTask does not)

$singletask = new SingleTask();
$singletask->setNextRun($event_start);

$this->em->persist($singletask);

$event->setSingleTask($singletask);

$this->em->flush();

【问题讨论】:

  • 如果你已经有了 singletask 对象,为什么还要再去获取它?
  • @JasonRoman 很好的观察。我已经删除了 SingleTask 对象的冗余获取,并更新了我上面问题中的代码。结果仍然没有变化(这是 SingleTask 数据库行没有变化)。
  • 你能发布更多关于你如何创建事件的代码吗?如果事件已经存在,则无需再次调用persist,只需flush。另外,您不需要说->setSingleTask,因为您已经从$event 中获取了它。
  • @JasonRoman 我已更新命令文件代码以显示如何从事件存储库中检索所有现有事件对象。我还删除了 persist() 调用,结果是一样的。据我了解,从 Event 对象中检索 SingleTask,更新其信息并将其设置回 Event 对象,然后刷新实体管理器就足够了......
  • 一条评论——你可以跳过循环中的$event->setSingleTask($singletask);,因为它已经与事件相关联,你可以将$this->em->flush();移到foreach()之外——它会处理所有的最后更新而不是通过每个循环迭代。但我必须问显而易见的。查看您的数据库...您确定这些事件有一个与之关联的任务实体吗?看起来您没有在单个任务上设置事件 - 检查数据库中的事件,看看 event_id 是否为空(我也不允许 nullable 在这里)。

标签: php entity-framework symfony orm


【解决方案1】:

来自 cmets - 原来这是 $lastRun 变量的简单错字。映射到数据库的变量是$lastRun,但是你的设置是在做$this->lastrun;

由于变量名在 PHP 中区分大小写,因此您只是创建了一个新的公共类变量,但它并未映射到数据库。如果你使用 PHP 的严格模式来处理错误,它会捕捉到这个并抛出一个错误。

这是更新后的代码:

公共函数 setLastRun(\DateTime $lastRun = null) { $this->lastRun = $lastRun; }

【讨论】:

    【解决方案2】:

    我肯定会回答一些荒谬的问题,但我认为您的代码中唯一缺少的是:

    $this->em->persist($event);
    $this->em->flush();
    

    希望这能解决你的问题!

    【讨论】:

    • 很遗憾没有这样做。
    • 你有输出吗?
    猜你喜欢
    • 2016-01-20
    • 2016-06-23
    • 1970-01-01
    • 2019-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多