web-dev-qa-db-fra.com

Définir le champ d'entité doctrine entité au lieu de null

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
5
fliim

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.

1
Alvin Bunk

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. 

8
Joe

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.

1
Alvin Bunk

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.

0
Dan Costinel