san rojeru interfaz grafica diseño codigo animado java hibernate session orm flush

java - rojeru - Cuando Hibernate vacía una sesión, ¿cómo decide qué objetos de la sesión están sucios?



rojeru san (5)

Mi comprensión de Hibernate es que a medida que los objetos se cargan desde el DB, se agregan a la sesión. En varios puntos, dependiendo de su configuración, la sesión se vacía. En este punto, los objetos modificados se escriben en la base de datos.

¿Cómo decide Hibernate qué objetos son "sucios" y necesitan ser escritos?

¿Los proxies generados por las asignaciones de intercepción Hibernate a los campos, y agregar el objeto a una lista sucia en la sesión?

¿O Hibernate observa cada objeto en la Sesión y lo compara con el estado original de los objetos?

¿O algo completamente diferente?


Eche un vistazo a org.hibernate.event.def.DefaultFlushEntityEventListener.dirtyCheck. Cada elemento de la sesión va a este método para determinar si está sucio o no comparando con una versión intacta (una del caché o una de la base de datos).


Hibernate toma una instantánea del estado de cada objeto que se carga en la sesión. En color, cada objeto en la sesión se compara con su instantánea correspondiente para determinar cuáles están sucios. Las sentencias de SQL se emiten según sea necesario y las instantáneas se actualizan para reflejar el estado de los objetos de sesión (ahora limpios).


Hibernate puede / puede usar la generación de bytecode (CGLIB) para que sepa que un campo está sucio tan pronto como se llama al setter (o incluso se asigna al campo afaict).

Esto inmediatamente marca ese campo / objeto como sucio, pero no reduce la cantidad de objetos que deben ser verificados con suciedad durante el enjuague. Todo lo que hace es impactar la implementación de org.hibernate.engine.EntityEntry.requiresDirtyCheck() . Todavía hace una comparación de campo por campo para verificar la suciedad.

Digo lo anterior sobre la base de una red de arrastre reciente a través del código fuente (3.2.6GA), con cualquier credibilidad que se agregue. Puntos de interés son:

  • SessionImpl.flush() desencadena un evento onFlush() .
  • SessionImpl.list() llama a autoFlushIfRequired() que desencadena un evento onAutoFlush() . (en las tablas de interés). Es decir, las consultas pueden invocar un color. Curiosamente, no se produce una descarga si no hay ninguna transacción.
  • Ambos eventos finalmente terminan en AbstractFlushingEventListener.flushEverythingToExecutions() , que termina (entre otras ubicaciones interesantes) en flushEntities() .
  • Eso recorre todas las entidades de la sesión ( source.getPersistenceContext().getEntityEntries() ) llamando a DefaultFlushEntityEventListener.onFlushEntity() .
  • Eventualmente terminas en dirtyCheck() . Ese método hace algunas optimizaciones wrt a CGLIB banderas sucias, pero todavía hemos terminado bucle sobre cada entidad.