Doctrine 2: use default values โ€‹โ€‹0 instead of zero for relationship

Is it possible to use the value 0 instead of zero for relationships (many-to-one, one to one) using Doctrine 2?

Now I have many NOT NULL columns that I cannot change to null values. Changing the default value in MySQL to 0 is not a solution by itself. Becease doctrine always sets the column to insert / update rows.

+6
source share
1 answer

No, It is Immpossible.

NULL has a very specific meaning in SQL. It represents "no value", and you can make sure that your logic will not work even at the SQL level:

 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! */ 

No, you cannot maintain a Doctrine ORM so that 0 interpreted as NULL , as this is not permitted by the RDBMS itself.

What you can do is insert โ€œfakeโ€ reference records into your database, which will then act as a null object when hydrated as objects:

 INSERT INTO `bar` VALUES (NULL); UPDATE `bar` SET `id` = 0 WHERE `id` = 4; INSERT INTO `foo` VALUES (NULL, 0); /* now works! */ 

In terms of essence, it looks very similar.

(Note that public properties are supported ONLY by Doctrine ORM 2.4, which are not yet released, but they make reading easier here)

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

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

And then the code to create a new Foo instance:

 $nullBar = $entityManager->find('Bar', 0); $foo = new Foo(); $foo->bar = $nullBar; $em->persist($foo); $em->flush(); 
+8
source

All Articles