将学说实体布尔字段设置为 0 而不是 null

Posted

技术标签:

【中文标题】将学说实体布尔字段设置为 0 而不是 null【英文标题】:Set doctrine entity boolean field to 0 instead of null 【发布时间】:2017-08-31 06:01:22 【问题描述】:

我正在尝试使用值为 0 或 1 的布尔字段来保留一个学说实体。

当该属性设置为 true 时,它​​会在数据库中将其保存为 '1'。 但是当它为'false'或'0'时,它会在数据库中将其保存为NULL。

如何解决这个问题,只保存为 1 或 0?

我使用的属性的注释如下:

@ORM\Column(name="substitute", type="boolean", nullable=true)

当我将 nullable 设置为 false 时,我无法持久化它,因为它仍然想设置为 null。

谢谢

当我坚持它时,字段值为0

尝试 1 @ORM\Column(name="substitute", type="boolean", options="default":"0"))

错误:无法保存 null

尝试 2 @ORM\Column(name="substitute", type="boolean", nullable= true, options="default":"0"))

不起作用,它仍然在 base 中保存 null

信息 1

实际插入查询正在尝试插入 0。但我收到此错误“ORA-01400: cannot insert NULL into (\"MYBASE\".\"MYTABLE\".\"SUBSTITUTE\")”

信息 2

相同的附加到另一个实体

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;

坚持

$test = new TestEntity();
$test->setIsSubstitute(false);
$em->persist($test);

结果

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)" []

信息 3

使用 oci 或 oci8 驱动程序手动插入

sql> INSERT INTO TestEntity (test_entity_id, substitute) VALUES (13, 0)
[2017-04-06 11:21:15] 1 row affected in 62ms

【问题讨论】:

请记住,默认值:0 东西严格用于数据库。 Doctrine 本身不会在您的实体中设置任何默认值。私人 $substitute = false;应该管用。如果没有,那么您还有其他东西可以改变值。 调试 $em->persist($affectation) 行时,该字段值正确设置为 'false'。实际插入查询将'false'替换为'0',但我收到错误“无法插入NULL”...... 听起来像是配置问题或控制器问题。您的 Oracle 连接对其他实体是否正常工作?我想你已经正确设置了 oci8? @AlvinBunk 我正在使用 oci 驱动程序。 (不是 oci8)。我没有与此案有关的其他实体。 如果您将 Symfony 与 Oracle 一起使用,您应该使用 oci8。您的 parameters.yml 文件应该有:database_driver: oci8 如果您需要帮助,我创建了一篇关于 installing OCI8 on RHEL 的文章。基本上根据 Oracle 和 Underground PHP and Oracle Manual,你应该使用 oci8 和 PHP。 【参考方案1】:

只需将 SQL 默认设置为 0(编辑:您需要在更改后更新架构):

/**
 * @ORM\Column(type="boolean", options="default":"0")
 */
protected $isActive;

你也可以默认初始化属性:

/**
 * @ORM\Column(type="boolean", options="default":"0")
 */
protected $isActive = false;

只要将值设置为 true/false,Nullable 就无关紧要。

如果您在保存之前确实将属性设置为 false 并且它仍然将其保存为空值在数据库中,那么其他事情正在发生。

【讨论】:

感谢您的回答。我会尝试一下,然后告诉你它是否有效。 更改注解(并更新架构)@ORM\Column(name="substitute", type="boolean", options="default":"0" ))。他试图在不可为空的字段上设置 null。我会尝试设置 nullable=true 这真的很奇怪。你有调试器在运行吗?如果是这样,您应该在将属性写入数据库之前检查该属性是否真的设置为 true 或 false。您还可以查看 sfToolbar 并搜索对 DB 执行的实际查询,以检查从对象传递的值 您真的更新了架构并清除了缓存吗? 我没有清除缓存,只是更新了架构并检查了数据库上的字段属性是否已实际更改。【参考方案2】:

在您的 paramters.yml 文件中将您的驱动程序从 oci 更改为 oci8

database_driver: oci8

应该这样做。使用the Underground PHP and Oracle Manual 安装OCI8。

【讨论】:

【参考方案3】:

我觉得@Cerad 的建议是对的,你可以试试:

/**
 * @ORM\Column(name="substitute", type="boolean")
 */
protected $substitute = false;

让我们知道结果。

【讨论】:

我也这样做了。不工作。正如*我在评论中所说:实际插入查询正在尝试插入 0。但我收到此错误“ORA-01400: cannot insert NULL into (\"MYBASE\".\"MYTABLE\".\"SUBSTITUTE\" )"... 非常奇怪的行为 也许可以尝试通过控制台窗口连接到数据库并手动运行一个简单的 INSERT INTO 语句。【参考方案4】:

我刚刚复制了您的案例,并成功保存到数据库中 1 为真,0 为假。

例子:

//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');

我希望我能很好地理解你的问题。

【讨论】:

你是否使用带有 pdo_oci 驱动程序的 oracle 数据库? @fliim 哦,对不起,这个例子是使用旧的好 mysql 作为 RDBM。【参考方案5】:

您可以使用$em->getReference(EntityName::class, "AnyValue"); 创建假对象

编码愉快。

【讨论】:

Cab 你再解释一下?为什么需要这样的“假物体”?

以上是关于将学说实体布尔字段设置为 0 而不是 null的主要内容,如果未能解决你的问题,请参考以下文章

angular 下拉框null默认值

使MS Access号码字段显示为空而不是0

位类型:默认为 '0' 而不是 NULL

CodeIgniter - 如何将表单中的值发布为 NULL 而不是 0

我怎么能阻止JPA将embeddable对象设置为null只是因为它的所有字段都是null?

Laravel - 将 Select2 默认设置为 NULL 而不是第一个选项