Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-2302

entity not updating with existing \Datetime object

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Invalid
    • Affects Version/s: 2.1.7
    • Fix Version/s: None
    • Component/s: ORM
    • Security Level: All
    • Labels:
      None
    • Environment:
      ubuntu 12.04
      PHP 5.3.10
      PostgreSQL 8.4
      Symfony 2.0.15

      Description

      Within an entity i have an method to add days to a subscription. For that an datetime object is modified.

      But the database is not going to be updated if an already existing datetime-object is modified an set. It's only working when an freshly created datetime object is used.

      NOT WORKING EXAMPLE:

          public function addDaysToSubscription($days) {
      
              if ($this->hasValidSubscription()) {
      
                  $startFromDate = $this->getSubscriptionValidUntil();
              }
              else {
      
                  $startFromDate = new \DateTime('now');
              }
      
              $this->setSubscriptionValidUntil($startFromDate->modify('+' . $days .' days'));
          }
      

      WORKAROUND:

          public function addDaysToSubscription($days) {
      
              if ($this->hasValidSubscription()) {
      
                  $validDate = $this->getSubscriptionValidUntil()->format('Y-m-d H:i:s');
                  $startFromDate = new \DateTime($validDate);
              }
              else {
      
                  $startFromDate = new \DateTime('now');
              }
      
              $this->setSubscriptionValidUntil($startFromDate->modify('+' . $days .' days'));
          }
      

        Activity

        Stephan Tijink created issue -
        Hide
        Benjamin Eberlei added a comment -

        From the documentation (Mapping Objects):

        DateTime and Object types are compared by reference, not by value. Doctrine updates this values if the reference changes and therefore behaves as if these objects are immutable value objects.
        

        You have to replace them with a new instance.

        Show
        Benjamin Eberlei added a comment - From the documentation (Mapping Objects): DateTime and Object types are compared by reference, not by value. Doctrine updates this values if the reference changes and therefore behaves as if these objects are immutable value objects. You have to replace them with a new instance.
        Benjamin Eberlei made changes -
        Field Original Value New Value
        Status Open [ 1 ] Resolved [ 5 ]
        Resolution Fixed [ 1 ]
        Hide
        Stephan Tijink added a comment -

        Whats the reason for this behaviour ? For me it seem not very intuitive and cost me a couple of hours of project time

        Show
        Stephan Tijink added a comment - Whats the reason for this behaviour ? For me it seem not very intuitive and cost me a couple of hours of project time
        Hide
        Marco Pivetta added a comment - - edited

        Stephan Tijink there is no real "global" way of comparing objects in PHP. The only way would be to use a non-strict comparison (aka `==` vs `===`), and that leads to many unexpected problems.

        Since `DateTime` instances are objects like any other, the comparison is applied with `===`.

        This the safest way to handle this is to work with it as if it was an immutable:

        public function setCreationTime(\DateTime $dateTime)
        {
            $this->creationTime = clone $dateTime;
        }
        
        public function getCreationTime(\DateTime $dateTime)
        {
            return clone $this->creationTime;
        }
        

        This basically disallows a lot of unexpected behaviors, even when not working with the ORM.

        Show
        Marco Pivetta added a comment - - edited Stephan Tijink there is no real "global" way of comparing objects in PHP. The only way would be to use a non-strict comparison (aka `==` vs `===`), and that leads to many unexpected problems. Since `DateTime` instances are objects like any other, the comparison is applied with `===`. This the safest way to handle this is to work with it as if it was an immutable: public function setCreationTime(\DateTime $dateTime) { $ this ->creationTime = clone $dateTime; } public function getCreationTime(\DateTime $dateTime) { return clone $ this ->creationTime; } This basically disallows a lot of unexpected behaviors, even when not working with the ORM.
        Hide
        Benjamin Eberlei added a comment -

        Also DateTime objects being mutable was a mistake in PHP, this is why 5.5 will have DateTimeImmutable, which we will switch to if possible in the future

        Show
        Benjamin Eberlei added a comment - Also DateTime objects being mutable was a mistake in PHP, this is why 5.5 will have DateTimeImmutable, which we will switch to if possible in the future
        Benjamin Eberlei made changes -
        Resolution Fixed [ 1 ]
        Status Resolved [ 5 ] Reopened [ 4 ]
        Hide
        Benjamin Eberlei added a comment -

        Change to 'Invalid'

        Show
        Benjamin Eberlei added a comment - Change to 'Invalid'
        Benjamin Eberlei made changes -
        Status Reopened [ 4 ] Resolved [ 5 ]
        Resolution Invalid [ 6 ]

        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-2302, expand=changesets[0:20].revisions[0:29],reviews}, methodType=GET}] : Received status code 503 (Service Temporarily Unavailable)

          People

          • Assignee:
            Benjamin Eberlei
            Reporter:
            Stephan Tijink
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: