首页 > 解决方案 > Doctrine 不会保留修改后的数据

问题描述

所以我试图在 Doctrine 中坚持一个实体。我希望保留的对象看起来像从 Symfony dump() 函数中提取的:

Time {#7751 ▼
  -id: 3
  -timeIn: DateTime {#7749 ▶}
  -timeOut: null
  -rateId: Rate {#7761 ▼
    -id: 1
    -amount: "30.00"
    -name: "Technical"
    -projectId: Project {#7756 ▶}
    -groupId: 1
  }
  -description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
  -userId: 1
  -status: "Unpaid"
  -total: null
  -cost: "60.00"
  -projectId: Project {#7756 ▼
    -id: 1
    -name: "Acme Corp"
    -description: "Metals Company"
    -contactId: 1
    -organizationId: 1
    -groupId: 1
  }
  -groupId: 1
  }

现在我显然不能坚持这一点,因为我在他们的 ID 中有相应的对象。例如:rateId、projectId 等。因此,为了弥补这一点,在我的 clockOut 函数中,我运行检查以将对象替换为存储的 ID。请参阅下面的clockOut函数:

public function clockOut($time, $group = null){
    dump($time);
    if(gettype($time) == "object"){
        if(gettype($time->getProjectId())=='object'){
            $time->setProjectId($time->getProjectId()->getId());
        }
        if(gettype($time->getRateId())=='object'){
            $time->setRateId($time->getRateId()->getId());
        }
        $this->persistClockout($time);
    }
    elseif(gettype($time) == "string"){
        if($group == null){
            return false;
        }else {
            $time = $this->findData($group, $time);
            $this->persistClockout($time);
        }
    }else {
        return false;
    }
}

还有一个对应的 persistClockout 函数处理实际的打卡和小时计算。尽管我认为这与我遇到的问题没有任何关系,但无论如何我都会将其包括在内,因为它是相关的。

/**
 * Persist time
 */
private function persistClockout($time, $group = null){
    if($time->getTimeOut() == null){
        $time->setTimeOut(new DateTime("Now"));
    }
    $this->hours = $this->hoursCalculate($time->getTimeIn(), $time->getTimeOut());
    $time->setTotal($this->hours);
    dump($time);
    die();
    $this->persist($time);
}

/**
 * Get the amount of hours spent in decimal format.
 */
private function hoursCalculate($past, $present){
    $diff = $present->diff($past);
    $hours = round($diff->s / 3600 + $diff->i / 60 + $diff->h + $diff->days * 24, 2);
    return $hours;
}

现在你可以看到我在命令结束之前运行了 dump() 函数,因为我一直在尝试自己诊断这个问题。根据 dump() 函数,数据如下所示:

Time {#7751 ▼
  -id: 3
  -timeIn: DateTime {#7749 ▶}
  -timeOut: DateTime {#11571 ▶}
  -rateId: 1
  -description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
  -userId: 1
  -status: "Unpaid"
  -total: 187.83
  -cost: "60.00"
  -projectId: 1
  -groupId: 1
}

伟大的!这就是预期的结果。但是当我开始尝试对数据库进行实际持久化时,问题就来了。

An exception occurred while executing 'UPDATE rate SET project_id = ? WHERE id = ? AND group_id = ?' with params [{}, 1, 1]:

Notice: Object of class ProjectBundle\Entity\Project could not be converted to int

虽然我在运行 persist 函数之前检查了数据,但似乎仍然认为 projectId 仍然是一个对象,即使我确保将其设置为实际 Id 而不是对象,它也会忽略我。

我进一步查看了 Symfony 分析器,发现了学说用来更新和查看细节的部分,你瞧 projectId 是一个对象吗?即使那不是我传递的?

列出参数的 Symfony Profiler SQL 更新。

有人知道发生了什么吗?抱歉这篇冗长的帖子,我只是想给你们一些关于你们正在使用什么的信息。请忽略代码中的 dump() 和 die() 函数,我一直在使用它们来尝试诊断,但我很困惑。值得注意的是,我已经尝试过运行诸如 php bin/console cache:clear 之类的磨坊程序,并重新启动服务器。

提前谢谢你堆栈溢出!

编辑:

下面是为 ->persist() 列出的代码

    public function persist($entity, bool $flush = true)
{
    $this->manager->persist($entity);

    if ($flush) {
        $this->flush();
    }

    return $this;
}

更新

我尝试运行坚持,然后单独刷新,但没有奏效。得到了同样的例外。老实说,我在这里不知所措。

标签: phpsymfonydoctrine

解决方案


我认为您需要使用此代码:

$this->flush($time); 

代替$this->persist($time);


推荐阅读