Оживляем Doctrine 2 Document/Entity при получении из кэша

// Январь 24th, 2013 // Doctrine 2

Zombie-iconНедавно столкнулись на работе с такой проблемой. При получении объекта (Doctrine 2 Document) из кэша все методы, которые у него вызываются, возвращают пустое значение. Особенно интересно было смотерть на это, когда ttl кэша был 10 секунд, и при обновлении страницы результаты то были, то пропадали. 

 

Задача

Ну, например, есть у нас объект Пользователь. А у него есть связанные с ним объекты книг. При этом вызывая метод $user->getBooks() в случае, когда объекта «свежий» (т.е. его нет в кэше) — мы получаем книги. А вот когда для следующего запроса он берется из кэша — то возвращается NULL. Почему так происходит?

Объяснение

Проблема в том, что такой объект — «мертвый», а именно он находится в состоянии DETACHED в DocumentManager/EntityManager и работать с его связями не получится. Но выход есть.

Решение

Можно «оживить» его, а именно приаттачить к текущему экземпляру DocumentManager/EntityManager, так, чтобы он стал в состояние MANAGED. Для этого есть функция merge.

/**
* Merges the state of a detached document into the persistence context
* of this DocumentManager and returns the managed copy of the document.
* The document passed to merge will not become associated/managed with this DocumentManager.
*
* @param object $document The detached document to merge into the persistence context.
* @return object The managed copy of the document.
*/
public function merge($document)
{
if (!is_object($document)) {
throw new \InvalidArgumentException(gettype($document));
}
$this->errorIfClosed();
return $this->unitOfWork->merge($document);
}

Для этого выполняем такую команду:

$user = $this->_dm->merge($user);

$this->_dm — это экземпляр DocumentManager.

Резюме

После получения Doctrine Document/Entity из кэша обязательно делаем ему merge!

Ссылки

Entities in session

Share

Спасибо!


Если вам помогла статья, или вы хотите поддержать мои исследования и блог - вот лучший способ сделать это:


Комментировать