Доктрина и неразрешенные отношения

Я вижу неожиданный эффект кеширования в Доктрине (1.2.4).

У меня есть пара связанных таблиц, определенных следующим YAML (несколько дополнительных полей, которые не используются в примере, удалены). Просто простые отношения «1-Много» от студентов к школам.

School: tableName: tblschool columns: sch_id: name: sch_id as id primary: true autoincrement: true type: integer(4) sch_name: name: sch_name as name type: string(50) Student: tableName: tblstudent columns: stu_id: name: stu_id as id primary: true autoincrement: true type: integer(4) stu_sch_id: name: stu_sch_id as school_id type: integer(4) relations: School: local: school_id foreign: id foreignAlias: Students 

Я могу создать простой запрос Doctrine (1.2.4), чтобы вернуть ученика с

  $result1 = Doctrine_Query::create() ->from('Student s') ->where('s.id = 1') ->execute(); 

а затем извлеките соответствующее название школы с помощью

 foreach ($result1 as $result) { $ans[] = $result->School["name"]; } 

Теперь я изменяю school_id (который вызывает отношения), следуя этому:

 foreach ($result1 as $result) { $result["school_id"] = 1 - $result["school_id"]; $result->save(); } 

(Я создал БД так, чтобы это дало еще один действительный идентификатор школы).

Если бы я был сейчас, немедленно, попытайтесь получить доступ к отношениям, я получу имя старой школы. Я это понимаю – это потому, что я не вызвал refreshRelated (). То, что я нахожу неожиданным, состоит в том, что если я немедленно сделаю другой запрос, дублирующий первый

  $result2 = Doctrine_Query::create() ->from('Student s') ->where('s.id = 1') ->execute(); 

и получить его результат

 foreach ($result2 as $result) { $ans[] = $result->School["name"]; } 

когда я просматриваю содержимое своего массива, я нахожу, что в обоих случаях у меня одно и то же имя школы. Другими словами, хотя я сделал второй запрос и смотрю на результат запроса, связь не обновляется.

Данные в базе данных являются точными и согласованными; т.е. существуют соответствующие ученики и школы. Например, выполнение указанной последовательности второй раз – при выполнении другой программы – использует другое название школы (хотя повторное дублирование).

Откуда это кэширование?

Solutions Collecting From Web of "Доктрина и неразрешенные отношения"

Доктрина использует небольшое кэширование в отношениях: ваша Student->School хранится в атрибуте Student , а ваш Student->school_id тоже в другом атрибуте.

Когда вы меняете свой Student->school_id , Student->school_id базу данных, а Student->school_id , а Student->School – нет, так как регидратация этого объекта может быть расширением CPU / memory.

Doctrine предоставляет некоторый метод для обновления отношений , но это способность разработчика использовать его.

Пример :

 $student->refreshRelated('School'); //refreshes only the School relation $student->refreshRelated(); //refreshes every relation of the $student - $student->refreshRelated('School'); //refreshes only the School relation $student->refreshRelated(); //refreshes every relation of the $student 

Но есть еще одно кэширование. Doctrine хранит все гидратированные объекты в памяти, чтобы ограничить номер запроса. Поэтому, когда вы снова запрашиваете своего ученика, вы обнаружите, что ваша Student->School не изменилась.