Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-657

DateTime objects casted to string in query results

    Details

    • Type: New Feature New Feature
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.3
    • Component/s: ORM
    • Security Level: All
    • Labels:
      None
    • Environment:
      Linux, PostgreSQL 8.4

      Description

      As we read in the documentation, 'datetime' fields are casted by Doctrine to PHP DateTime class objects. However, when we want to get only certain fields from a table using DQL, Doctrine casts the datetime value to ordinary string. Consider the following example:

      Column definition
      /**
       * @var DateTime $active
       *
       * @Column(name="registered", type="datetime")
       */
      private $registered;
      
      Query
      var_dump($em->createQuery('SELECT u.id, u.registered FROM Entities\\User u')->getResult());
      

      Expected result:

      • The returned row contains DateTime object for 'registered' column.

      Actual result:

      • The returned row contains string for 'registered' column.

      If this is an intended feature, first of all, it should be clearly pointed in the documentation that Doctrine types do not apply in such situations, and secondly, I think it is a very bad practice. I use Doctrine and tell him I have a datetime field in order to get Datetime objects automatically, not to deal with manual conversions.

        Activity

        Tomasz Jędrzejewski created issue -
        Tomasz Jędrzejewski made changes -
        Field Original Value New Value
        Description As we read in the documentation, 'datetime' fields are casted by Doctrine to PHP DateTime class objects. However, when we want to get only certain fields from a table using DQL, Doctrine casts the datetime value to ordinary string. Consider the following example:

        Column definition:
        ~~~~
        /**
         * @var DateTime $active
         *
         * @Column(name="registered", type="datetime")
         */
        private $registered;
        ~~~~

        Query:
        ~~~~
        var_dump($em->createQuery('SELECT u.id, u.registered FROM Entities\\User u')->getResult());
        ~~~~

        Expected result:

        * The returned row contains DateTime object for 'registered' column.

        Actual result:

        * The returned row contains string for 'registered' column.

        If this is an intended feature, first of all, it should be clearly pointed in the documentation that Doctrine types do not apply in such situations, and secondly, I think it is a very bad practice. I use Doctrine and tell him I have a datetime field in order to get Datetime objects automatically, not to deal with manual conversions.
        As we read in the documentation, 'datetime' fields are casted by Doctrine to PHP DateTime class objects. However, when we want to get only certain fields from a table using DQL, Doctrine casts the datetime value to ordinary string. Consider the following example:

        {code:title=Column definition|borderStyle=solid}
        /**
         * @var DateTime $active
         *
         * @Column(name="registered", type="datetime")
         */
        private $registered;
        {code}

        {code:title=Query|borderStyle=solid}
        var_dump($em->createQuery('SELECT u.id, u.registered FROM Entities\\User u')->getResult());
        {code}

        Expected result:

        * The returned row contains DateTime object for 'registered' column.

        Actual result:

        * The returned row contains string for 'registered' column.

        If this is an intended feature, first of all, it should be clearly pointed in the documentation that Doctrine types do not apply in such situations, and secondly, I think it is a very bad practice. I use Doctrine and tell him I have a datetime field in order to get Datetime objects automatically, not to deal with manual conversions.
        Hide
        Benjamin Eberlei added a comment -

        oh wait, i am just now looking at your query, you are retrieving the values as scalar fields, that is something totally different. Let me check the code on this issue.

        Show
        Benjamin Eberlei added a comment - oh wait, i am just now looking at your query, you are retrieving the values as scalar fields, that is something totally different. Let me check the code on this issue.
        Benjamin Eberlei made changes -
        Comment [ Can you specify exactly which versions of Doctrine 2 you are using? i.e. what ORM package and what DBAL package? We made a pretty significant change in the conversion in the last days, it maybe that you mixed the wrong packages. ]
        Hide
        Tomasz Jędrzejewski added a comment -

        ORM - the newest one from Git. I couldn't find any matching version in the issue form, so I selected nothing.
        DBAL - the version that currently works with ORM. I've already noticed that DBAL-master does not work with the newest ORM .

        Show
        Tomasz Jędrzejewski added a comment - ORM - the newest one from Git. I couldn't find any matching version in the issue form, so I selected nothing. DBAL - the version that currently works with ORM. I've already noticed that DBAL-master does not work with the newest ORM .
        Hide
        Benjamin Eberlei added a comment -

        Ok the problem is that currently scalar values retrieved from a DQL query are not converted to their PHP value. This affects scalar values only, if you rewrite the query to:

        SELECT u FROM Entities\User u
        

        you will get the Entities\User class with a DateTime instance in the "registered" variable.

        Show
        Benjamin Eberlei added a comment - Ok the problem is that currently scalar values retrieved from a DQL query are not converted to their PHP value. This affects scalar values only, if you rewrite the query to: SELECT u FROM Entities\User u you will get the Entities\User class with a DateTime instance in the "registered" variable.
        Hide
        Tomasz Jędrzejewski added a comment -

        So far, I simply added a manual conversion that checks if the object was returned or not, so it will still work once the bug is fixed. In my case, sometimes I prefer to retrieve certain columns only, because the entire row can be quite big.

        Show
        Tomasz Jędrzejewski added a comment - So far, I simply added a manual conversion that checks if the object was returned or not, so it will still work once the bug is fixed. In my case, sometimes I prefer to retrieve certain columns only, because the entire row can be quite big.
        Hide
        Benjamin Eberlei added a comment -

        I think we should really fix this using an additional bit of information on the ResultSetMapping to hint the hydrators which type a scalar value is, if its an entity field, otherwise do nothing in conversion.

        Array or Object fields, or even complex objects and serialization structs are pretty useless otherewise

        Show
        Benjamin Eberlei added a comment - I think we should really fix this using an additional bit of information on the ResultSetMapping to hint the hydrators which type a scalar value is, if its an entity field, otherwise do nothing in conversion. Array or Object fields, or even complex objects and serialization structs are pretty useless otherewise
        Hide
        Roman S. Borschel added a comment -

        Scheduled for 2.1 for now.

        Show
        Roman S. Borschel added a comment - Scheduled for 2.1 for now.
        Roman S. Borschel made changes -
        Fix Version/s 2.1 [ 10022 ]
        Hide
        Benjamin Eberlei added a comment -

        Convert to feature (from bug)

        Show
        Benjamin Eberlei added a comment - Convert to feature (from bug)
        Benjamin Eberlei made changes -
        Issue Type Bug [ 1 ] New Feature [ 2 ]
        Hide
        Jan Volf added a comment -

        I'm observing this problem on ORM 2.0.3 package with MySQL database and I would really expect this conversion to be implicit.
        The Docs (12.7.1. Query Result Formats) says:

        Query#getArrayResult(): Retrieves an array graph (a nested array) that is largely interchangeable with the object graph generated by Query#getResult() for read-only purposes.

        But it is not interchangeable at all.

        Anyway: It can potentially be an issue when dealing with timezones as the as it exposes the date in it's original format stored in DB, eventually without timezone on most DB engines. To interpret the such date the same way as Doctrine when hydrating to Object, one would need to know what timezone uses doctrine to interpret the DB timestamps without timezone.

        Show
        Jan Volf added a comment - I'm observing this problem on ORM 2.0.3 package with MySQL database and I would really expect this conversion to be implicit. The Docs (12.7.1. Query Result Formats) says: Query#getArrayResult(): Retrieves an array graph (a nested array) that is largely interchangeable with the object graph generated by Query#getResult() for read-only purposes. But it is not interchangeable at all. Anyway: It can potentially be an issue when dealing with timezones as the as it exposes the date in it's original format stored in DB, eventually without timezone on most DB engines. To interpret the such date the same way as Doctrine when hydrating to Object, one would need to know what timezone uses doctrine to interpret the DB timestamps without timezone.
        Benjamin Eberlei made changes -
        Fix Version/s 2.x [ 10090 ]
        Fix Version/s 2.1 [ 10022 ]
        Fabio B. Silva made changes -
        Assignee Roman S. Borschel [ romanb ] Fabio B. Silva [ fabio.bat.silva ]
        Hide
        Guilherme Blanco added a comment -

        We have a nearly done PR for this issue: https://github.com/doctrine/doctrine2/pull/251
        As soon as Fabio changes the pointed optimizations, this issue will be closed.

        Show
        Guilherme Blanco added a comment - We have a nearly done PR for this issue: https://github.com/doctrine/doctrine2/pull/251 As soon as Fabio changes the pointed optimizations, this issue will be closed.
        Show
        Fabio B. Silva added a comment - Fixed since this commit : https://github.com/doctrine/doctrine2/commit/ea14bcff4a2a78bf774e8847b6645dca112f9757
        Fabio B. Silva made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Fix Version/s 2.3 [ 10185 ]
        Fix Version/s 2.x [ 10090 ]
        Resolution Fixed [ 1 ]
        Benjamin Eberlei made changes -
        Workflow jira [ 11558 ] jira-feedback [ 14477 ]
        Benjamin Eberlei made changes -
        Workflow jira-feedback [ 14477 ] jira-feedback2 [ 16341 ]
        Benjamin Eberlei made changes -
        Workflow jira-feedback2 [ 16341 ] jira-feedback3 [ 18594 ]

        This list may be incomplete, as errors occurred whilst retrieving source from linked applications:

        • Request to http://www.doctrine-project.org/fisheye/ failed: Error in remote call to 'FishEye 0 (http://www.doctrine-project.org/fisheye/)' (http://www.doctrine-project.org/fisheye) [AbstractRestCommand{path='/rest-service-fe/search-v1/crossRepositoryQuery', params={query=DDC-657, expand=changesets[0:20].revisions[0:29],reviews}, methodType=GET}] : Received status code 503 (Service Temporarily Unavailable)

          People

          • Assignee:
            Fabio B. Silva
            Reporter:
            Tomasz Jędrzejewski
          • Votes:
            1 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: