2014-08-30 57 views
2

我在學說中的OneToOne關係上有一個複合主鍵的問題。當一個對象沒有任何關係(這通常是可能的),我得到了以下錯誤消息:Doctrine2 oneToOne複合主鍵不可爲空

Doctrine\Common\Proxy\Exception\OutOfBoundsException: Missing value for 
primary key idEngine on Farkas\CoreBundle\Entity\Engine 

我在學說直接發現了問題:

vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php Line 2116 

// TODO: Is this even computed right in all cases of composite keys? 
foreach ($assoc['targetToSourceKeyColumns'] as $targetColumn => $srcColumn) { 
    $joinColumnValue = isset($data[$srcColumn]) ? $data[$srcColumn] : null; 
    if ($joinColumnValue !== null) { 
     if ($targetClass->containsForeignIdentifier) { 
      $associatedId[$targetClass->getFieldForColumn($targetColumn)] = $joinColumnValue; 
     } else { 
      $associatedId[$targetClass->fieldNames[$targetColumn]] = $joinColumnValue; 
     } 
    } 
} 

$joinColumnValue爲空當外鍵是空的,因爲包含行數據的數組$data沒有關係字段的數組鍵。待辦事項評論告訴我,組合鍵有問題嗎?

這裏我的兩個實體(只是小試,沒有想到我的實體^^的邏輯):

/** 
* Car 
* 
* @ORM\Table() 
* @ORM\Entity(repositoryClass="Farkas\CoreBundle\Entity\CarRepository") 
*/ 
class Car 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id_car", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="NONE") 
    */ 
    private $idCar; 


    /** 
    * @var string 
    * 
    * @ORM\Column(name="brand", type="string", length=255) 
    */ 
    private $brand; 

    /** 
    * @var string 
    * 
    * 
    * @ORM\OneToOne(targetEntity="Engine", mappedBy="car") 
    * @ORM\JoinColumns(
    * @ORM\JoinColumn(name="engine", referencedColumnName="id_engine"), 
    * @ORM\JoinColumn(name="country", referencedColumnName="country") 
    *) 
    */ 
    private $engine; 

    /** 
    * @var integer 
    * @ORM\Id 
    * @ORM\Column(name="country", type="integer") 
    */ 
    private $country; 
} 

第二

/** 
* Engine 
* 
* @ORM\Table() 
* @ORM\Entity(repositoryClass="Farkas\CoreBundle\Entity\EngineRepository") 
*/ 
class Engine 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id_engine", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="NONE") 
    */ 
    private $idEngine; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="engineName", type="string", length=255) 
    */ 
    private $engineName; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="description", type="string", length=255) 
    */ 
    private $description; 

    /** 
    * @var integer 
    * @ORM\Id 
    * @ORM\Column(name="country", type="integer") 
    */ 
    private $country; 

    /** 
    * @var integer 
    * 
    * @ORM\OneToOne(targetEntity="Car", inversedBy="engine") 
    * @ORM\JoinColumns(
    * @ORM\JoinColumn(name="car_id", referencedColumnName="id_car"), 
    * @ORM\JoinColumn(name="country", referencedColumnName="country") 
    *) 
    */ 
    private $car; 
} 

當我嘗試執行findAll()我收到了上面的錯誤消息。當我在MySQL直接執行生成的SQL,一切都看起來不錯:

SELECT t0.id_car AS id_car1, t0.brand AS brand2, t0.country AS country3, 
t0.engine AS engine4, t0.country AS country5 FROM Car t0 

這意味着,補水不能使用空oneToOne有關的工作。

+0

只是一個想法,爲什麼你不把你的發動機放在你的車上加入到發動機中,然後讓汽車和發動機的國家加入到一個新的國家對象中。那麼你可以在它們之間有空關係。 – 2014-08-31 20:51:29

+0

這個例子真的很愚蠢。這是我的真實代碼@work的樣子。 – 2014-09-01 11:10:19

回答

1

(發佈代表OP的。)

正如預期的那樣,這只是從我身邊一個錯誤。這是解決方案:

租車實體

/** 
* @var string 
* 
* 
* @ORM\OneToOne(targetEntity="Engine", mappedBy="car") 
* @ORM\JoinColumns(
* @ORM\JoinColumn(name="fk_engine", referencedColumnName="id_engine"), 
* @ORM\JoinColumn(name="fk_engine_country", referencedColumnName="country") 
*) 
*/ 
private $engine; 

引擎實體

/** 
* @var integer 
* 
* @ORM\OneToOne(targetEntity="Car", inversedBy="engine") 
* @ORM\JoinColumns(
* @ORM\JoinColumn(name="fk_car", referencedColumnName="id_car"), 
* @ORM\JoinColumn(name="fk_car_country", referencedColumnName="country") 
*) 
*/ 
private $car; 

的連接名稱列是會隨着數據庫內的關係字段創建一個屬性。我已經在桌子內有一個名字國家的屬性。所以最後這個名字始終是識別關係的外鍵。