14

I'm looking for a way to make doctrine using TIMESTAMP instead of DATETIME for MySql.

Additionaly I need to set ON UPDATE CURRENT_TIMESTAMP and CURRENT_TIMESTAMP as default values.

I would like to have the possibility to have all this code in PHP annotations to have everything in one central place.

How can I do that?

BetaRide
  • 16,207
  • 29
  • 99
  • 177

8 Answers8

28

After hours of searching, I found the answer and I hope this helps anyone else looking for a more satisfactory solution than entity lifecycles and the WRONG column type (because a TIMESTAMP is a particular type with specific behaviours beyond just storing a datetime value)

All you need to do is to add

 * @ORM\Column(type="datetime", nullable=false)
 * @ORM\Version

to your annotation and Doctrine will both create a TIMESTAMP column with DEFAULT CURRENT_TIMESTAMP and then return the actual table value as a valid \DateTime object.

CTOP (Credits to Original Poster)

LaurentG
  • 474
  • 4
  • 16
David Soussan
  • 2,698
  • 1
  • 16
  • 19
  • 1
    Why without Version it creates DateTime but with Version it creates Timestamp? – JorgeeFG Jan 05 '17 at 15:20
  • 2
    For that you would have to ask the people who wrote it. – David Soussan Apr 21 '17 at 12:40
  • 2
    The `version` attribute is flag to tell Doctrine that it can change the value in this column to keep track of where concurrent writes may impact the row data prior to the end of long running transaction. See [Optimistic Locking](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/transactions-and-concurrency.html#optimistic-locking). It is perhaps not a good idea to adopt this attribute for the sake of tripping Doctrine to use `timestamp` for your column. – Courtney Miles May 03 '17 at 05:37
4

There is no such thing like using TIMESTAMP in mysql with Doctrine. However, I fixed it myself but have to test it:

  • Create a file: Doctrine\DBAL\Types\TimestampType.php
  • Copy the code from TimeType.php into TimestampType.php
  • Rename 'Time' to 'Timestamp' in the code
  • Create a new constant, and add timestamp to the typesmap in: Doctrine\DBAL\Types\Type.php
  • Create function called getTimestampTypeDeclarationSQL in Doctrine\DBAL\Platforms\AbstractPlatform.php
  • And in that function, return TIMESTAMP

I've used yaml to create my Entities and Proxies, so use in yaml:

type: timestamp

I'm going to test this 'fix'/'workaround' now. I'll let you know.

LaurentG
  • 474
  • 4
  • 16
Polichism
  • 224
  • 1
  • 7
4

As suggested by Daniel Criconet,

@ORM\Column(type="datetime", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")

will make that particular column in the corresponding MySQL table become TIMESTAMP instead of DATETIME.

For YAML version, see the original answer.

iloo
  • 926
  • 12
  • 26
3
/**
 * @var \DateTime
 * @ORM\Column(type="datetime", columnDefinition="timestamp default current_timestamp")
 */
protected $createdAt;

/**
 * @var \DateTime
 * @ORM\Column(type="datetime", columnDefinition="timestamp default current_timestamp on update current_timestamp")
 */
protected $updatedAt;
sixty-nine
  • 147
  • 1
  • 5
2

@Polichism provided the right logic, but the patch wasn't accepted. Instead, users were directed to add a custom type. I've implemented that by combining:

The final versions can be found on GitHub:

NOTE: I've linked to specific commits to ensure that the links remain valid if the file is later removed. Use the history to check for newer versions.

claytond
  • 1,061
  • 9
  • 22
  • How did you solved field TIMESTAMP DEFAULT NULL when column is nullable issue? I've created custom type and it looks like working fine, but when I use doctrine:schema:create --dump-sql it generates "fieldName TIMESTAMP DEFAULT NULL" which is not a valid value for TIMESTAMP. Correct syntax is: "filedName TIMESTAMP NULL". Looks like I'll have to override the Platform implementation... any other ideas? – Anton Valqk Apr 15 '15 at 09:42
  • Frankly, I didn't --dump-sql to create my tables. The syntax also seems to be [valid for pgSQL](http://stackoverflow.com/a/9826915/1978687). For [MySQL](http://dev.mysql.com/doc/refman/5.6/en/timestamp-initialization.html), the syntax `timestamp NULL DEFAULT NULL` seems to be valid as well. To get Doctrine to add that first `NULL`, first try the `nullable` attribute in the [@Column annotation](http://doctrine-orm.readthedocs.org/en/latest/reference/annotations-reference.html#annref-column). Worst case, use the (non-portable) `columnDefinition` attribute. – claytond Apr 16 '15 at 13:43
1
/** @ORM\Column(type="datetime", nullable=false ) */
    protected $created;

this will create timestamp and return datetime object

 public function __construct()
        {
            $this->created = new \DateTime();

        }
Saurabh Chandra Patel
  • 12,712
  • 6
  • 88
  • 78
0

/** * @Column(type="datetime", options={"default": 0}) * @version=true */ private $data;

create sql like this: data TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL

tested on version 2.5.4

slaszu
  • 1
0

@ORM\Version works only for one property per entity so it is not an option if you need to have more than one timestamp field in a table.