Cuando Hibernate vaciados de una Sesión, ¿cómo decidir qué objetos en la sesión están sucios?

StackOverflow https://stackoverflow.com/questions/82429

Pregunta

Mi comprensión de la Hibernación es que a medida que los objetos se cargan de la base de datos que se añaden 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 Hibernate decidir qué objetos son 'sucio' y tiene que ser por escrito?

Hacer el proxy generado por Hibernate interceptar las asignaciones a los campos, y agregar el objeto a la sucia de la lista en la Sesión?

O hace Hibernar vistazo a cada objeto en la Sesión y compararlo con los objetos originales de estado?

O algo completamente diferente?

¿Fue útil?

Solución

Hibernate no/puede utilizar bytecode generación (CGLIB), por lo que sabe un campo es sucio, tan pronto como se llame el setter (o incluso asignar al campo afaict).

Esto inmediatamente que las marcas de campo/objeto como sucio, pero no reduce el número de objetos que deben ser sucio-se comprueban durante la descarga.Todo lo que hace es el impacto de la aplicación de org.hibernate.engine.EntityEntry.requiresDirtyCheck().Es todavía hace un campo por campo de comparación para comprobar la acumulación de suciedad.

Yo digo que el anterior, basado en un reciente red de arrastre a través del código fuente (3.2.6 GA), con lo que la credibilidad que añade.Puntos de interés son:

  • SessionImpl.flush() desencadena una onFlush() evento.
  • SessionImpl.list() llamadas autoFlushIfRequired() que provoca una onAutoFlush() evento.(en las tablas de interés).Es decir, las consultas pueden invocar un color.Curiosamente, ningún rubor se produce si no hay transacción.
  • Tanto los eventos que eventualmente terminan en AbstractFlushingEventListener.flushEverythingToExecutions(), que termina (entre otros sitios de interés) en flushEntities().
  • Que se repite a lo largo de cada entidad en el período de sesiones (source.getPersistenceContext().getEntityEntries()), llamando a DefaultFlushEntityEventListener.onFlushEntity().
  • Que, finalmente, terminan en dirtyCheck().Ese método hace algunas optimizaciones wrt para CGLIB sucio banderas, pero aún tenemos terminó un bucle por cada entidad.

Otros consejos

Hibernate toma una instantánea del estado de cada objeto que se carga en el período de Sesiones.En color, cada objeto de la Sesión es en comparación con su correspondiente instantánea para determinar cuáles son sucios.Las sentencias SQL se emiten como se requiere, y las instantáneas se actualiza para reflejar el estado de la (limpia) los objetos de Sesión.

Echa un vistazo a org.hibernate.evento.def.DefaultFlushEntityEventListener.dirtyCheck Cada elemento en la sesión va a este método para determinar si está sucio o no mediante la comparación con una virgen versión (uno de la caché o uno de la base de datos).

Hibernate defecto sucio mecanismo de comprobación de se tratará de corriente conectado entidades y hacer coincidir todas las propiedades, en contra de su carga inicial de tiempo de los valores.

Usted puede visualizar mejor este proceso en el siguiente diagrama:

Default automatic dirty checking

Estas respuestas son incompletas (en el mejor de los casos -- no soy un experto aquí).Si usted tiene una hib hombre entidad en su sesión, usted no hace NADA, usted todavía puede obtener una actualización emitido cuando se llama a guardar() sobre él.cuando?cuando otra sesión actualizaciones de objeto entre su carga() y save().aquí está mi ejemplo de esto: hibernate conjuntos sucia bandera (y actualización) aunque el cliente no el valor de cambio de

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top