2013-03-19 61 views
6

對於關係(多對一,一對一)使用Doctrine 2是否可以使用值0而不是null?學說2:使用默認的0值而不是空的關係

現在我有很多非空列女巫我可能不會更改爲空值。 將MySQL中的默認值更改爲0它本身不是解決方案becease doctrine總是設置插入/更新行的列。

回答

8

不,這是不可能的。

NULL在SQL中有非常具體的含義。它表示「沒有價值」,你可以驗證你的邏輯甚至不會在SQL級別上工作:

CREATE TABLE foo (
    `id` INT(11) PRIMARY KEY AUTO_INCREMENT, 
    `bar_id` INT(11) 
); 

CREATE TABLE `bar` (`id` INT(11) PRIMARY KEY AUTO_INCREMENT); 

ALTER TABLE foo ADD FOREIGN KEY `bar_id_fk` (`bar_id`) REFERENCES `bar` (`id`); 

INSERT INTO `bar` VALUES (NULL); 
INSERT INTO `bar` VALUES (NULL); 
INSERT INTO `bar` VALUES (NULL); 
INSERT INTO `foo` VALUES (NULL, 1); 
INSERT INTO `foo` VALUES (NULL, 2); 
INSERT INTO `foo` VALUES (NULL, 3); 
INSERT INTO `foo` VALUES (NULL, 0); 

/* 
    ERROR 1452 (23000): 
     Cannot add or update a child row: a foreign key constraint fails 
     (`t2`.`foo`, CONSTRAINT `foo_ibfk_1` FOREIGN KEY (`bar_id`) 
     REFERENCES `bar` (`id`)) 
*/ 

INSERT INTO `foo` VALUES (NULL, 4); 

/* 
    ERROR 1452 (23000): 
     Cannot add or update a child row: a foreign key constraint fails 
     (`t2`.`foo`, CONSTRAINT `foo_ibfk_1` FOREIGN KEY (`bar_id`) 
     REFERENCES `bar` (`id`)) 
*/ 

INSERT INTO `foo` VALUES (NULL, NULL); /* VALID! */ 

所以,不,你不能有學說ORM的表現,使0被解釋爲NULL,因爲這是不RDBMS本身允許。

你可以做的是將「假」,在你的數據庫中引用的條目,然後將在作爲實體水合作爲null object

INSERT INTO `bar` VALUES (NULL); 
UPDATE `bar` SET `id` = 0 WHERE `id` = 4; 

INSERT INTO `foo` VALUES (NULL, 0); /* now works! */ 

在實體方面,它看起來非常相似。

(請注意,public屬性僅支持從學說ORM 2.4,這是尚未發佈他們使事情更容易讀到這裏,雖然)

Foo.php:

use Doctrine\ORM\Mapping as ORM; 

/** 
* @ORM\Entity() 
* @ORM\Table(name="foo") 
*/ 
class Foo 
{ 
    /** 
    * @ORM\Column(type="integer") 
    * @ORM\Id() 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    public $id; 

    /** 
    * @ORM\ManyToOne(targetEntity="Bar") 
    * @ORM\JoinColumn(name="bar_id", referencedColumnName="id", nullable=false) 
    */ 
    public $bar; 
} 

酒吧.PHP:

use Doctrine\ORM\Mapping as ORM; 

/** 
* @ORM\Entity() 
* @ORM\Table(name="bar") 
*/ 
class Bar 
{ 
    /** 
    * @ORM\Column(type="integer") 
    * @ORM\Id() 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    public $id; 
} 

然後代碼產生一個新的Foo實例:

$nullBar = $entityManager->find('Bar', 0); 
$foo  = new Foo(); 
$foo->bar = $nullBar; 

$em->persist($foo); 
$em->flush(); 
+0

有沒有難過的感覺,我喜歡被糾正:) – Sam 2013-03-20 06:22:12

+1

感謝您的正確和明確的答案。 – 2013-03-20 07:48:55

+0

我知道這很糟糕,但我們只是使用'postLoad'事件將零值fk設置爲'null'。似乎工作。請參閱下面的代碼回覆。 – Florian 2014-02-24 18:06:31