doctrine / orm

Doctrine Object Relational Mapper (ORM)
https://www.doctrine-project.org/projects/orm.html
MIT License
9.94k stars 2.52k forks source link

Doctrine fails to apply DEFAULT CURRENT_TIMESTAMP for DateTime field #11702

Open Legend999 opened 3 weeks ago

Legend999 commented 3 weeks ago

Bug Report

Q A
doctrine/orm 3.3.0
doctrine/dbal 4.2.1
database 10.4.28-MariaDB

Summary

Doctrine fails to apply the default timestamp for a field defined with DEFAULT CURRENT_TIMESTAMP. When persisting an entity without manually setting the date, it raises a "column cannot be null" error, despite the database schema having a default value set.

Current behavior

Uncaught PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'sent_at' cannot be null in vendor/doctrine/dbal/src/Driver/PDO/Statement.php:55

Expected behavior

Doctrine should use the default timestamp set in the schema (DEFAULT CURRENT_TIMESTAMP), allowing to create new entities without explicitly setting the value.

How to reproduce

  1. Define a Doctrine entity with a datetime column that has a default value of CURRENT_TIMESTAMP, as shown below:
    #[Entity]
    #[Table(name: 'messages')]
    class Message
    {
    #[Column(name: 'sent_at', type: Types::DATETIME_IMMUTABLE, updatable: false, options: ['default' => 'CURRENT_TIMESTAMP'])]
    private readonly DateTimeImmutable $sent_at;
    // ...
    }
  2. Generate the schema using orm:schema-tool:create --dump-sql, resulting in SQL similar to:
    CREATE TABLE messages (
    id int unsigned AUTO_INCREMENT NOT NULL,
    sent_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
    message text NOT NULL,
    PRIMARY KEY (id)
    );
  3. Attempt to create a new Message entity without setting the sent_at property:
    $message = new Message($message);
    $this->entity_manager->persist($message);
    $this->entity_manager->flush();

Additional information

The issue seems to be specific to PHP/Doctrine, as running a raw SQL INSERT INTO messages (message) VALUES ('message') correctly assigns the sent_at field to the current timestamp.