There seems to be a bug when updating the object #6644

Closed
opened 2026-01-22 15:36:25 +01:00 by admin · 3 comments
Owner

Originally created by @StasToken on GitHub (Mar 6, 2021).

I encountered an obvious bug when Doctrine does not save the model value to the database when updating the object
use:

        "doctrine/annotations": "^1.0",
        "doctrine/doctrine-bundle": "^2.2",
        "doctrine/doctrine-migrations-bundle": "^3.0",
        "doctrine/orm": "^2.8",

I use it in my symfony 5 project (I will give an abbreviated model just to reflect the whole point)

namespace App\Entity;

use App\Repository\SubscriptionsRepository;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\Index;
use App\Services\Month;
/**
 * @ORM\Entity(repositoryClass=SubscriptionsRepository::class)
 * @ORM\Table(name="`subscriptions`",indexes={
 *     @ORM\Index(name="stop_time_idx", columns={"stop_time"}),
 * })
 */
class Subscriptions
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="datetime")
     */
    private $stop_time;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getStopTime(): ?\DateTimeInterface
    {
        return $this->stop_time;
    }

    public function setStopTime(\DateTimeInterface $stop_time): self
    {
        $this->stop_time = $stop_time;

        return $this;
    }
}

I want to update the field with time:

$subscriptions = $this->getDoctrine()->getRepository(Subscriptions::class)->find(1);
$date = $subscriptions->getStopTime();
dump($date);
$date->modify('+'.$extra_time_sec.'seconds');
dump($date);
$em = $this->getDoctrine()->getManager();
$em->persist($subscriptions);
$em->flush();

Note that 1 day was added to the DateTime object (Note that the object ID doctrine/DoctrineBundle#1001 and doctrine/DoctrineBundle#1001 is the same object)

Controller.php on line 141:
DateTime @1615592508 {#1001
  date: 2021-03-12 23:41:48.0 UTC (+00:00)
}
Controller.php on line 146:
DateTime @1615678908 {#1001
  date: 2021-03-13 23:41:48.0 UTC (+00:00)
}

The procedure for saving the change to the database was called, but the object was not saved. The UPDATE request was not executed (I looked at the logs, it was not executed, I did not even try)

I racked my head for a long time what's the matter, I somehow came up with the idea that Doctrine does not save the object because it does not know that it has changed, since the DateTime object itself remained the same - it was just modified I decided to check it by simply creating a new object

$subscriptions = $this->getDoctrine()->getRepository(Subscriptions::class)->find(1);
$date = $subscriptions->getStopTime();
dump($date);
$date = clone $date;
$date->modify('+'.$extra_time_sec.'seconds');
dump($date);
$em = $this->getDoctrine()->getManager();
$em->persist($subscriptions);
$em->flush();

Note that the object IDs [#1001 and doctrine/DoctrineBundle#96] are now different

Controller.php on line 141:
DateTime @1615592508 {#1001
  date: 2021-03-12 23:41:48.0 UTC (+00:00)
}
Controller.php on line 146:
DateTime @1615678908 {#96
  date: 2021-03-13 23:41:48.0 UTC (+00:00)
}

Now saving to the database goes as expected!

WTF - It's very similar to the fact that Doctrine does not know that the object has been updated, I do not know how normal this is, to be honest it looks more like a jamb.. - in general, I decided to inform the developers about this behavior, because it can confuse other people.

Originally created by @StasToken on GitHub (Mar 6, 2021). I encountered an obvious bug when Doctrine does not save the model value to the database when updating the object use: ``` "doctrine/annotations": "^1.0", "doctrine/doctrine-bundle": "^2.2", "doctrine/doctrine-migrations-bundle": "^3.0", "doctrine/orm": "^2.8", ``` I use it in my symfony 5 project (I will give an abbreviated model just to reflect the whole point) ``` namespace App\Entity; use App\Repository\SubscriptionsRepository; use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping\Index; use App\Services\Month; /** * @ORM\Entity(repositoryClass=SubscriptionsRepository::class) * @ORM\Table(name="`subscriptions`",indexes={ * @ORM\Index(name="stop_time_idx", columns={"stop_time"}), * }) */ class Subscriptions { /** * @ORM\Id * @ORM\GeneratedValue * @ORM\Column(type="integer") */ private $id; /** * @ORM\Column(type="datetime") */ private $stop_time; public function getId(): ?int { return $this->id; } public function getStopTime(): ?\DateTimeInterface { return $this->stop_time; } public function setStopTime(\DateTimeInterface $stop_time): self { $this->stop_time = $stop_time; return $this; } } ``` I want to update the field with time: ``` $subscriptions = $this->getDoctrine()->getRepository(Subscriptions::class)->find(1); $date = $subscriptions->getStopTime(); dump($date); $date->modify('+'.$extra_time_sec.'seconds'); dump($date); $em = $this->getDoctrine()->getManager(); $em->persist($subscriptions); $em->flush(); ``` Note that 1 day was added to the DateTime object (Note that the object ID doctrine/DoctrineBundle#1001 and doctrine/DoctrineBundle#1001 is the same object) ``` Controller.php on line 141: DateTime @1615592508 {#1001 date: 2021-03-12 23:41:48.0 UTC (+00:00) } Controller.php on line 146: DateTime @1615678908 {#1001 date: 2021-03-13 23:41:48.0 UTC (+00:00) } ``` The procedure for saving the change to the database was called, **but the object was not saved**. The UPDATE request was not executed (I looked at the logs, it was not executed, I did not even try) I racked my head for a long time what's the matter, I somehow came up with the idea that Doctrine does not save the object because it does not know that it has changed, since the DateTime object itself remained the same - it was just modified I decided to check it by simply creating a new object ``` $subscriptions = $this->getDoctrine()->getRepository(Subscriptions::class)->find(1); $date = $subscriptions->getStopTime(); dump($date); $date = clone $date; $date->modify('+'.$extra_time_sec.'seconds'); dump($date); $em = $this->getDoctrine()->getManager(); $em->persist($subscriptions); $em->flush(); ``` Note that the object IDs [#1001 and doctrine/DoctrineBundle#96] are now different ``` Controller.php on line 141: DateTime @1615592508 {#1001 date: 2021-03-12 23:41:48.0 UTC (+00:00) } Controller.php on line 146: DateTime @1615678908 {#96 date: 2021-03-13 23:41:48.0 UTC (+00:00) } ``` **Now saving to the database goes as expected!** WTF - It's very similar to the fact that Doctrine does not know that the object has been updated, I do not know how normal this is, to be honest it looks more like a jamb.. - in general, I decided to inform the developers about this behavior, because it can confuse other people.
admin closed this issue 2026-01-22 15:36:25 +01:00
Author
Owner

@beberlei commented on GitHub (Mar 6, 2021):

Its not a bug, datetime objects are compared by reference not by value. This is documented afaik

@beberlei commented on GitHub (Mar 6, 2021): Its not a bug, datetime objects are compared by reference not by value. This is documented afaik
Author
Owner

@StasToken commented on GitHub (Mar 6, 2021):

And how can I make some kind of forced save? to not make a clone of the object and then it's stupid...

@StasToken commented on GitHub (Mar 6, 2021): And how can I make some kind of forced save? to not make a clone of the object and then it's stupid...
Author
Owner

@beberlei commented on GitHub (Mar 6, 2021):

You can use datetimeimmutablw instead then modify returns a new instance

@beberlei commented on GitHub (Mar 6, 2021): You can use datetimeimmutablw instead then modify returns a new instance
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#6644