【问题标题】:Set doctrine entity boolean field to 0 instead of null将学说实体布尔字段设置为 0 而不是 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。

标签: php symfony doctrine-orm doctrine


【解决方案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 你再解释一下?为什么需要这样的“假物体”?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多