2011-06-16 17 views
7

Veo un efecto de almacenamiento en caché inesperado en Doctrine (1.2.4).Doctrina y relaciones no regeneradas

Tengo un par de tablas relacionadas definidas por el siguiente YAML (varios campos adicionales no utilizados en el ejemplo eliminado). Simplemente una simple relación de 1 a muchos de los estudiantes a las escuelas.

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 

puedo crear una doctrina sencilla (1.2.4) consulta para volver a un estudiante con

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

y luego extraer el nombre de la escuela correspondiente con

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

ahora modifique el school_id (que causa la relación) siguiendo esto con:

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

(Configuré la base de datos para que esto dé otra identificación escolar válida).

Si fuera ahora, de inmediato, intente acceder a la relación Voy a obtener el nombre de la vieja escuela. Entiendo esto, es porque no he llamado a refreshRelated(). Lo que encuentro inesperado es que si yo inmediatamente realizar otra petición duplicación de la primera

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

y obtener su resultado

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

cuando examine el contenido de mi serie me parece que, en ambos casos , Tengo el mismo nombre de escuela. En otras palabras, aunque he hecho una segunda consulta y estoy viendo el resultado de la consulta, la relación no se actualiza.

Los datos en la base de datos son correctos y consistentes; es decir, existen alumnos y escuelas apropiados. P.ej. ejecutar la secuencia anterior una segunda vez - en una ejecución de programa diferente - utiliza el otro nombre de la escuela (aunque nuevamente duplicado).

¿De dónde viene este almacenamiento en caché?

Respuesta

11

Doctrine use un poco de almacenamiento en caché en las relaciones: su Student->School se almacena en un atributo Student, y su Student->school_id también, en otro atributo.

Cuando cambie su Student->school_id, la base de datos obtener queryied, y el cambio Student->school_id, pero el Student->School no, como la rehidratación de este objeto podría ser la CPU/memoria expansiva.

Doctrine proporciona some method to refresh the relations, pero es responsabilidad del desarrollador usarla.

Ejemplo:

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

Pero hay otro almacenamiento en caché. Doctrine mantiene todo el objeto hidratado en la memoria, para limitar el número de solicitud. Por lo tanto, cuando realiza una nueva consulta para su estudiante, descubre que su Student->School no ha cambiado.