简体   繁体   中英

Doctrine's PreUpdate lifecycle callback updates all loaded entities and not only the updated one

I have a doctrine entity in my symfony 5 application with "createdAt" and "updatedAt" fields. As I found it in different sources, I use lifecycle callbacks to set the values automatically:

/**
 * @ORM\Entity(repositoryClass=CoinRepository::class)
 * @ORM\HasLifecycleCallbacks()
 */
class Coin
{
    ...

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

    /**
     * @ORM\Column(type="datetime", nullable=true)
     */
    private ?\DateTime $updatedAt = null;

    /**
     * @ORM\PrePersist()
     */
    public function prePersist(): void
    {
        $this->setInsertedAt(new \DateTime());
    }

    /**
     * @ORM\PreUpdate()
     */
    public function preUpdate(): void
    {
        $this->setUpdatedAt(new \DateTime());
    }

    ...

    public function getInsertedAt(): \DateTime
    {
        return $this->insertedAt;
    }

    public function setInsertedAt(\DateTime $insertedAt): void
    {
        $this->insertedAt = $insertedAt;
    }

    public function getUpdatedAt(): ?\DateTime
    {
        return $this->updatedAt;
    }

    public function setUpdatedAt(?\DateTime $updatedAt): void
    {
        $this->updatedAt = $updatedAt;
    }
}

The problem is now, that if I load all Coins and only update one of them, every coin is getting the new "updatedAt" value. Here is my code:

$coins = $this->entityManager->getRepository(Coin::class)->findAll();
foreach ($coins as $coin) {
    $this->coinUpdater->update($coin);

    die; // Just to show that only one coin is updated
}

And the "update" function of the "coinUpdater":

public function update(Coin $coin): void
{
    // Enrich coin
    ...

    $this->entityManager->flush();
}

If I run this in a command by console I can see the doctrine debug and that each coin is updated and in database I can see that each coin has the new "updatedAt" value now. I have not found anything about the problem. Does anyone have any idea?

I have found the problem. I have a field "totalSupply" and I declared it like this:

/**
 * @ORM\Column(type="bigint")
 */
private int $totalSupply;

The problem is, that if you use the type "bigint" the variable must have the type "string". But because I defined it as "int" I always had this changeset:

array(1) {
  ["totalSupply"]=>
  array(2) {
    [0]=>
    string(7) "1999999"
    [1]=>
    int(1999999)
  }
}

And that's why each coin was updated on flush. I defined the variable as string now and now it is working as expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM