J'essaie de conserver une entité de doctrine avec un champ booléen où les valeurs sont 0 ou 1.
Lorsque la propriété est définie sur true, elle est enregistrée comme base "1" dans la base de données. Mais lorsqu'elle est "false" ou comme "0", elle est enregistrée comme base NULL.
Comment puis-je résoudre ce problème pour enregistrer uniquement en tant que 1 ou 0?
L'annotation pour la propriété que j'utilise ressemble à ceci:
@ORM\Column(name="substitute", type="boolean", nullable=true)
Lorsque je mets la valeur false à false, je ne peux pas la persister, car elle souhaite toujours définir la valeur sur null.
Merci
Quand je persiste, la valeur du champ est 0
Tentative 1 @ ORM\Column (name = "substitute", type = "boolean", options = {"default": "0"})
erreur: impossible de sauvegarder null
Tentative 2 @ ORM\Column (name = "substitute", type = "boolean", nullable = true, options = {"default": "0"})
Ne fonctionne pas, sauvegarde toujours null en base
Info 1
La requête d'insertion essaye d'insérer 0. Mais j'ai l'erreur "ORA-01400: impossible d'insérer NULL dans (\" MYBASE\". \" MYTABLE\". \" SUBSTITUTE\")"
Info 2
Même append avec une autre entité
class TestEntity
{
/**
* @ORM\Column(name="test_entity_id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(name="substitute", type="boolean")
*/
private $isSubstitute = false;
}
Persistant
$test = new TestEntity();
$test->setIsSubstitute(false);
$em->persist($test);
Résultat
request.CRITICAL: Uncaught PHP Exception Doctrine\DBAL\Exception\NotNullConstraintViolationException: "An exception occurred while executing 'INSERT INTO TestEntity (test_entity_id, substitute) VALUES (?, ?)' with params [7, 0]: SQLSTATE[HY000]: General error: 1400 OCIStmtExecute: ORA-01400: cannot insert NULL into ("MYBASE"."TESTENTITY"."SUBSTITUTE") (ext\pdo_oci\oci_statement.c:148)"\n (ext\\pdo_oci\\oci_statement.c:148) at PATH\\vendor\\doctrine\\dbal\\lib\\Doctrine\\DBAL\\Driver\\PDOStatement.php:91)"} []
Info 3
L'insertion manuelle fonctionne à l'aide de oci ou du pilote oci8
sql> INSERT INTO TestEntity (test_entity_id, substitute) VALUES (13, 0)
[2017-04-06 11:21:15] 1 row affected in 62ms
Changez votre pilote de oci
en oci8
dans votre fichier parameters.yml:
database_driver: oci8
Ça devrait le faire. Utilisez Underground PHP et Oracle Manual pour installer OCI8.
Il suffit de définir le paramètre SQL par défaut sur 0 ( Modifier: vous devez mettre à jour le schéma après cette modification ):
/**
* @ORM\Column(type="boolean", options={"default":"0"})
*/
protected $isActive;
Aussi, vous pouvez initialiser la propriété par défaut:
/**
* @ORM\Column(type="boolean", options={"default":"0"})
*/
protected $isActive = false;
Nullable ne devrait pas avoir d'importance tant que la valeur est définie sur true/false.
Si vous définissez vraiment la propriété sur false avant de sauvegarder et que vous la sauvegardez comme nulle dans la base de données, il se passe autre chose.
Je pense que la suggestion de @ Cerad est correcte, pouvez-vous essayer:
/**
* @ORM\Column(name="substitute", type="boolean")
*/
protected $substitute = false;
Faites-nous savoir le résultat.
Je viens de reproduire votre cas et j'ai réussi à enregistrer dans la base de données 1 pour true et 0 pour false.
Exemple:
//Entity
Person: id, name, isMajor(boolean field)
//IMPORTANT: I setted the boolean field inside __construct() method, and let it be, by default, false (0). This means you don't need anymore to have that options={"default":"0"}.
//...
/**
* @var bool
*
* @ORM\Column(name="isMajor", type="boolean", nullable=true)
*/
private $isMajor;
public function __construct()
{
$this->isMajor = false;
}
//Created CRUD against the Entity
//When saving (either using the default actions provided by the CRUD, or by setting the values inside another controller's action):
//AppBundle/Controller/DefaultController.php
/**
* @Route("/new-person")
*/
public function createAction()
{
$person = new Person();
$person->setName('name');
$person->setIsMajor(true); // this saves 1 in the table
$person->setIsMajor(false); // this saves 0 in the table
$em = $this->getDoctrine()->getManager();
$em->persist($person);
$em->flush();
return $this->redirectToRoute('person_index');
}
J'espère avoir bien compris votre problème.