[英]Doctrine won't persist modified data
因此,我試圖將一個實體堅持在教義中。 我要保留的對象看起來像是從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是一個對象嗎? 即使那不是我所傳遞的?
有人不知道這是怎么回事嗎? 不好意思,我只是想給大家一些有關您正在使用的工具的信息。 請忽略代碼中的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;
}
更新
我試着持續運行,然后分別刷新,但沒有用。 有同樣的例外。 老實說,我在這里很茫然。
我認為您需要使用以下代碼:
$this->flush($time);
而不是$this->persist($time);
我想到了。 事實證明,教義如何識別不同的數據以及它認為相同的數據是一個問題。 我認為這與效率或緩存有關,也與這些方面有關。
無論如何,讓我告訴你我是如何得出這個結論的。
我得到的第一個提示是,雖然rateId最初是一個對象,后來又轉換為它的對應ID,但它沒有像ProjectId那樣引發錯誤。
其次,我仔細檢查了dump()函數並發現了一些東西。 (我將重用原始帖子中的示例)
Time {#7751 ▼
-id: 3
-timeIn: DateTime {#7749 ▶}
-timeOut: null
-rateId: Rate {#7761 ▼
-id: 1
-amount: "30.00"
-name: "Technical"
-projectId: Project {#7756 ▶} <---- Right Here
-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 ▼ <---- Right Here
-id: 1
-name: "Acme Corp"
-description: "Metals Company"
-contactId: 1
-organizationId: 1
-groupId: 1
}
-groupId: 1
}
項目對象后的數字相同。 因此,我提出了一個理論,即該理論將原始對projectId(對象)的引用存儲在某個位置,然后使用該值而不是我后來設置為相應ID(整數)的值。
因此,為了檢驗該理論,我編寫了兩個函數來“平鋪”我的對象,從對象樹的末尾開始(因為它實際上最多只能嵌套3個嵌套對象),直到開始。 這樣,即使最終將它們“刪除”,所有參考也都匹配。
/**
* Undo all object associations and convert them back into their original IDs.
* @param object $data
* @param array $callable
*/
public function flattenObject($data, $callable){
$sorter = new SortingHelper;
foreach($callable as $call){
$getMethod = 'get'.ucfirst($call).'Id';
$setMethod = 'set'.ucfirst($call).'Id';
if(method_exists($data, $getMethod)){
$found = $data->$getMethod();
if(gettype($found) == 'object'){
$result = $this->flatten($found, $callable);
$data->$setMethod($result);
}
}
}
return $data;
}
/**
* @param object $data
* @param array $callable
*/
private function flatten($data, $callable){
for($i = 0; $i != count($callable); $i++){
$getMethod = 'get'.ucfirst($callable[$i]).'Id';
$setMethod = 'set'.ucfirst($callable[$i]).'Id';
if(method_exists($data, $getMethod)){
$result = $data->$getMethod();
if(gettype($result) == 'object'){
$data->$setMethod($result->getId());
}
}
}
return $data->getId();
}
運行flattenObject()函數使我可以將對象持久保存到數據庫中,因為對ID的引用不再是對象。
am 超級煩人的問題解決了。
我希望這會在將來對某人有所幫助。 謝謝大家的貢獻! :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.