Оживляем Doctrine 2 Document/Entity при получении из кэша
// 24 января, 2013 // Doctrine 2
Недавно столкнулись на работе с такой проблемой. При получении объекта (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!
Ссылки
Спасибо!
Если вам помогла статья, или вы хотите поддержать мои исследования и блог - вот лучший способ сделать это: