| Кэширование ORM в Kohana |
| Monday, 12 December 2011 | |
|
Потратил много времени на обнаружение неочевидной особенности поведения системы кэширования объектов, получаемых из базы с использованием встроенной системы ORM Kohana в случае, если в свойствах модели не указано явно название таблицы, ей соответствующей. Если вы инициализируете значение $_table_name ORM-модели в ее конструкторе (как в примере ниже):
class Model_Foo extends ORM
{
protected $_db = 'default';
protected $_primary_key = 'id';
protected $_primary_val = 'name';
...
public function __construct($id = NULL)
{
$this->_table_name = 'foo_table';
...
parent::__construct($id);
}
...
}
, то при попытке загрузить закэшированные данные с помощью конструкции вида:
$foos = ORM::factory('foo')->cached(7200)->find_all();
вы получите, увы, вовсе не закэшированный результат, а вполне себе актуальные данные (которые, конечно же, будут получены ценой запроса к БД, которого вы хотели избежать) Такое поведение Kohana обусловлено тем, что при чтении объекта из кэша и его последующей корректной десериализации подгружается файл с описанием класса вашей модели Model_Foo, однако его конструктор не вызывается и, соответственно, имя таблицы не инициализируется. Так как поля таблицы в модели не описаны, Kohana пытается загрузить список полей из таблицы, соответствующей названию модели в множественном числе - для примера выше это `foos`. Если такой таблицы в базе данных не находится, то генерируется исключение, которое интерпретируется системой кэширования как признак поврежденого кэша и обрабатывается втихую - возвращая NULL вместо данных. В результате данные загружаются каждый раз из базы данных, несмотря на то, что присутствуют в кэше. Таким образом, явное указание $_table_name необходимо в тех моделях, выборки для которых вы хотите хранить в кэше и успешно доставать оттуда же. Хочу особенно отметить, что при загрузке и десериализации объекта из кэша Kohana для него не вызывается автоматически конструктор. Это необходимо учитывать и инициализировать свойства (которые при обычной загрузке устанавливаются в конструкторе) при обращении к методам загруженного из кэша объекта, если они (методы) эти свойства используют. |

