簡體   English   中英

教義不會保留修改后的數據

[英]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是一個對象嗎? 即使那不是我所傳遞的?

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;
}

更新

我試着持續運行,然后分別刷新,但沒有用。 有同樣的例外。 老實說,我在這里很茫然。

我認為您需要使用以下代碼:

$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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM