Doctrine 2 ORM DateTime field in identifier

前端 未结 2 1603
别跟我提以往
别跟我提以往 2020-12-04 16:09

In our DB tables, we columns refID and date are a composite primary key, with one field of the identifier being mapped as a datetime:<

相关标签:
2条回答
  • 2020-12-04 16:37

    Doctrine 2 ORM needs to convert identifier fields to strings in the UnitOfWork. This is required to have the EntityManager being able to track changes to your objects.

    Since objects of type DateTime don't natively implement method __toString, converting them to strings is not as simple as casting them to strings.

    Therefore, the default date, datetime and time types are not supported as part of the identifier.

    To deal with it, you should define your own custom field type mydatetime mapped to your own MyDateTime class which implements __toString. That way, the ORM can handle identifiers also if they contain objects.

    Here's an example of how that class may look like:

    class MyDateTime extends \DateTime 
    {
        public function __toString()
        {
            return $this->format('U');
        }
    }
    

    And here's an example of how the custom DBAL type would look like:

    use Doctrine\DBAL\Types\DateTimeType;
    use Doctrine\DBAL\Platforms\AbstractPlatform;
    
    class MyDateTimeType extends DateTimeType
    {
        public function convertToPHPValue($value, AbstractPlatform $platform)
        {
            $dateTime = parent::convertToPHPValue($value, $platform);
            
            if ( ! $dateTime) {
                return $dateTime;
            }
    
            return new MyDateTime('@' . $dateTime->format('U'));
        }
    
        public function requiresSQLCommentHint(AbstractPlatform $platform)
        {
            return true;
        }
    
        public function getName()
        {
            return 'mydatetime';
        }
    }
    

    Then you register it with your ORM configuration during bootstrap (depends on the framework you are using). In symfony, it is documented on the symfony doctrine documentation.

    After that, you can use it in your entities:

    class corpWalletJournal
    {
        // ...
    
        /**
         * @ORM\Column(name="date", type="mydatetime", nullable=false)     
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="NONE")
         */
        private $date;
    
    0 讨论(0)
  • 2020-12-04 16:54

    Be careful with

    return new DateTimeEx('@' . $dateTime->format('U'));
    

    The timezone won't be good. You should do :

    $val = new DateTimeEx('@' . $dateTime->format('U'));
    $val->setTimezone($dateTime->getTimezone());
    
    return $val;
    
    0 讨论(0)
提交回复
热议问题