Обратный вызов жизненного цикла до обновления доктрины обновляет все загруженные сущности, а не только обновленную

#php #symfony #doctrine

Вопрос:

У меня есть сущность доктрины в моем приложении symfony 5 с полями «createdAt» и «updatedAt». Как я нашел в разных источниках, я использую обратные вызовы жизненного цикла для автоматической установки значений:

 /**
 * @ORMEntity(repositoryClass=CoinRepository::class)
 * @ORMHasLifecycleCallbacks()
 */
class Coin
{
    ...

    /**
     * @ORMColumn(type="datetime")
     */
    private DateTime $insertedAt;

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

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

    /**
     * @ORMPreUpdate()
     */
    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;
    }
}

 

Проблема в том, что теперь, если я загружу все монеты и обновлю только одну из них, каждая монета получит новое значение «updatedAt». Вот мой код:

 $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
}
 

И функция «обновление» «coinUpdater»:

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

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

Если я запущу это в командной консоли, я смогу увидеть отладку доктрины и то, что каждая монета обновляется, а в базе данных я вижу, что теперь каждая монета имеет новое значение «updatedAt». Я ничего не нашел об этой проблеме. У кого-нибудь есть какие-нибудь идеи?

Ответ №1:

Я нашел проблему. У меня есть поле «totalSupply», и я объявил его так:

 /**
 * @ORMColumn(type="bigint")
 */
private int $totalSupply;
 

Проблема в том, что если вы используете тип «bigint», переменная должна иметь тип «string». Но поскольку я определил его как «int», у меня всегда был этот набор изменений:

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

И именно поэтому каждая монета обновлялась на флеш. Теперь я определил переменную как строку, и теперь она работает так, как ожидалось.