@Kutuzov_ska

Как обновить вложенный объект в doctrine?

Добрый день!
Есть два класса:

class User {
    // ...

    // Здесь уже описан кастомный тип counter отнаследованный от JsonType
    #[Column(type: 'counter')]
    private Counter $counter;

    // ...
}

class Counter implements \JsonSerializable {
    private int $value = 0;

    // ...

    public function add() {
        ++$this->value;
    }

    // 
}

// ...

$user->getCounter()->add();
$em->flush();


В момент выполнения сохранения, даже если перед этим сделать persist, обновляется все, кроме counter. В момент создания сущности, json поле заполянется правильно.Я знаю примерно почему это происходит, доктрина не видит изменений т.к. сравнивает counter по ссылке. Делаю вывод, что можно решать пробелму через clone и другими эврестическими решениями:

// Вариант 1
$user->setCounter(clone $user->getCounter());

// Вариант 2
#[Entity]
#[HasLifecycleCallbacks]
class User {
    // ...

    #[PreUpdate]
    public function updateCounter(): void
    {
        $this->counter = clone $this->counter;
    }
}


Но есть ли какой нибудь элегантный способ? Например: Сделать поле обязательно обновляемым или изменить правила проверки.
  • Вопрос задан
  • 79 просмотров
Пригласить эксперта
Ответы на вопрос 1
Maksclub
@Maksclub
maksfedorov.ru
Да, ваши поля сущности должны быть иммутабельными, чтобы все корректно работало.
Делать поле иммутабельным и работать с сущностью через иммутабельность — есть элегантный способ

// Вариант 1
$user->setCounter(clone $user->getCounter());


Доработайте в
$user->raiseCount();

// User.php

public function raiseCount(): void
{
     $this->counter = $this->counter->add();
}


// Counter.php

public function add(): self
{
     $self = clone $this;
     ++$self->value;

     return $self;
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы