¿Cuál es el uso de session.flush () en Hibernate?

110

Cuando estamos actualizando un registro, podemos usarlo session.flush()con Hibernate. ¿Para qué es necesario flush()?

CHANTI
fuente

Respuestas:

138

Vaciar la sesión fuerza a Hibernate a sincronizar el estado en memoria del Sessioncon la base de datos (es decir, escribir cambios en la base de datos). De forma predeterminada, Hibernate eliminará los cambios automáticamente:

  • antes de algunas ejecuciones de consultas
  • cuando se confirma una transacción

Permitir vaciar explícitamente Sessionbrinda un control más preciso que puede ser necesario en algunas circunstancias (para obtener una ID asignada, para controlar el tamaño de la sesión, ...).

Pascal Thivent
fuente
8
Tenga en cuenta que esta respuesta describe el comportamiento DEFAULT Hibernate: el comportamiento de descarga se puede cambiar a través de la configuración del Modo de descarga. Los detalles están en docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/… (versión 3.5).
SteveT
1
Encontré el documento donde se dice exactamente lo que está diciendo, pero tengo la duda de que cuál será la prioridad significa que suponga 1) Tengo una clase en la que estoy guardando el objeto usando el código id = session.save(obj);y la transacción se confirma en la siguiente línea, pero obj no se guarda a DB, ¿por qué? 2) Guardé obj usando session.save(obj);con commit y mientras regresaba usé return obj.getprimaryID();En este caso obj se guarda en DB. Entonces, ¿por qué ocurre este comportamiento?
Amogh
74

Como se dijo correctamente en las respuestas anteriores, al llamar flush()forzamos a hibernar a ejecutar los comandos SQL en la base de datos. Pero entienda que los cambios aún no están "comprometidos". Entonces, después de realizar el vaciado y antes de realizar la confirmación, si accede directamente a la base de datos (por ejemplo, desde el indicador SQL) y verifica las filas modificadas, NO verá los cambios.

Esto es lo mismo que abrir 2 sesiones de comandos SQL. Y los cambios realizados en 1 sesión no son visibles para los demás hasta que se confirman.

Kaushik Lele
fuente
12
Bueno, los cambios pueden ser ligeramente visibles. Por ejemplo, una fila no confirmada puede crear un bloqueo en la fila insertada pero no confirmada y retrasar la inserción de la misma fila en otra sesión hasta que la transacción se confirme o deshaga. Entonces no es completamente invisible.
rghome
2
He navegado por toda la web y esta es la respuesta que finalmente me hizo obtenerla. Gracias.
Siddhartha
¿De qué sirve poner .flush () en un bucle for, si commit () hace un flush al final?
Eildosa
@Kaushik Lele ¿Cuál es el punto de flush () si los datos no son visibles después de flush? ¿Puede explicar algunos de los casos de uso más precisos en los que esto resulta útil?
java_geek
28

Solo sé que cuando llamamos, session.flush()nuestras declaraciones se ejecutan en la base de datos pero no se confirman.

Supongamos que no llamamos al flush()método en el objeto de sesión y si llamamos al método de confirmación, internamente hará el trabajo de ejecutar declaraciones en la base de datos y luego confirmar.

commit=flush+commit (en caso de funcionalidad)

Por lo tanto, concluyo que cuando llamamos al método flush () en el objeto Session, entonces no se confirma sino que llega a la base de datos y ejecuta la consulta y también se retrocede.

Para confirmar usamos commit () en el objeto Transaction.

Shoaib Chikate
fuente
¿Puede darnos algunos detalles sobre cuál es la necesidad de enjuagar?
java_geek
14

El vaciado de la sesión obtiene los datos que están actualmente en la sesión sincronizados con los que están en la base de datos.

Más en el sitio web de Hibernate:

flush()es útil, porque no hay absolutamente ninguna garantía sobre cuándo la sesión ejecuta las llamadas JDBC, solo el orden en el que se ejecutan, excepto que use flush().

miku
fuente
¿Puede proporcionar un escenario en el que el usuario deba preocuparse por la secuencia? El uso de hibernación es hacer que las cosas relacionadas con la base de datos sean transparentes para el usuario. Cuando "confirmamos", el vaciado ocurre automáticamente. ¿Cuál es el escenario en el que harás flush pero no te comprometerás?
Kaushik Lele
1
@KaushikLele puede consultar esta pregunta stackoverflow.com/questions/37382872/…
GMsoF
10

Puede usar flushpara forzar que las restricciones de validación se realicen y detecten en un lugar conocido en lugar de cuando se confirma la transacción. Puede ser que commitsea ​​llamado implícitamente por alguna lógica de marco, a través de la lógica declarativa, el contenedor o una plantilla. En este caso, cualquier excepción lanzada puede ser difícil de atrapar y manejar (podría ser demasiado alto en el código).

Por ejemplo, si tiene save()un nuevo objeto EmailAddress, que tiene una restricción única en la dirección, no obtendrá un error hasta que confirme.

Llamar flush()obliga a que se inserte la fila, lanzando una Excepción si hay un duplicado.

Sin embargo, tendrá que revertir la sesión después de la excepción.

rghome
fuente
4

Solo me gustaría agrupar todas las respuestas dadas anteriormente y también relacionar el método Flush () con Session.save () para dar más importancia

Hibernate save () se puede usar para guardar la entidad en la base de datos. Podemos invocar este método fuera de una transacción, por eso no me gusta este método para guardar datos. Si usamos esto sin transacción y tenemos una cascada entre entidades, entonces solo se guarda la entidad primaria a menos que vacíemos la sesión.

flush (): fuerza la sesión a vaciar. Se utiliza para sincronizar los datos de la sesión con la base de datos.

Cuando llama a session.flush (), las declaraciones se ejecutan en la base de datos pero no se confirma. Si no llama a session.flush () y si llama a session.commit (), el método commit () internamente ejecuta la declaración y confirma.

Así que commit () = flush + commit. Así que session.flush () simplemente ejecuta las declaraciones en la base de datos (pero no confirma) y las declaraciones ya NO ESTÁN EN LA MEMORIA. Simplemente obliga a que la sesión se descargue.

Pocos puntos importantes:

Debemos evitar guardar fuera del límite de la transacción, de lo contrario, las entidades mapeadas no se guardarán, lo que provocará una inconsistencia en los datos. Es muy normal olvidarse de vaciar la sesión porque no arroja ninguna excepción o advertencia. De forma predeterminada, Hibernate eliminará los cambios automáticamente: antes de algunas ejecuciones de consultas cuando se confirma una transacción.Permitir eliminar explícitamente la sesión brinda un control más preciso que puede ser necesario en algunas circunstancias (para obtener una ID asignada, para controlar el tamaño de la sesión )

Sundar Gsv
fuente
3

El flush() método hace que Hibernate vacíe la sesión. Puede configurar Hibernate para usar el modo de descarga para la sesión usando el setFlushMode()método. Para obtener el modo de descarga para la sesión actual, puede usar el getFlushMode()método. Para verificar si la sesión está sucia, puede usar el isDirty()método. De forma predeterminada, Hibernate gestiona el vaciado de las sesiones.

Como se indica en la documentación:

https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/flushing/Flushing.html

Enrojecimiento

El vaciado es el proceso de sincronizar el estado del contexto de persistencia con la base de datos subyacente. El EntityManagery el Hibernate Sessionexponen un conjunto de métodos, a través de los cuales el desarrollador de aplicaciones puede cambiar el estado persistente de una entidad.

El contexto de persistencia actúa como un caché transaccional de escritura diferida, poniendo en cola cualquier cambio de estado de la entidad. Como cualquier caché de escritura diferida, los cambios se aplican primero en la memoria y se sincronizan con la base de datos durante el tiempo de descarga. La operación de descarga toma cada cambio de estado de la entidad y lo traduce a una declaración INSERT, UPDATEo DELETE.

La estrategia de descarga viene dada por el flushMode de la sesión actual de Hibernate en ejecución. Aunque JPA define solo dos estrategias de descarga ( AUTOy COMMIT), Hibernate tiene un espectro mucho más amplio de tipos de descarga:

  • ALWAYS: Vacía la sesión antes de cada consulta;
  • AUTO: Este es el modo predeterminado y descarga la sesión solo si es necesario;
  • COMMIT: La sesión intenta retrasar el vaciado hasta que se confirme la transacción actual, aunque también podría vaciar prematuramente;
  • MANUAL: El vaciado de la sesión se delega a la aplicación, que debe llamar Session.flush()explícitamente para aplicar los cambios de contexto de persistencia.

De forma predeterminada, Hibernate usa el AUTOmodo de descarga que desencadena una descarga en las siguientes circunstancias:

  • antes de realizar una Transacción;
  • antes de ejecutar una consulta JPQL / HQL que se superpone con las acciones de la entidad en cola;
  • antes de ejecutar cualquier consulta SQL nativa que no tenga una sincronización registrada.

fuente
1

Llamar EntityManager#flushtiene efectos secundarios . Se usa convenientemente para tipos de entidad con valores de ID generados (valores de secuencia): tal ID está disponible solo tras la sincronización con la capa de persistencia subyacente. Si se requiere esta identificación antes de que finalice la transacción actual (para fines de registro, por ejemplo), se requiere vaciar la sesión.

johanwannheden
fuente
0

Con este método se evoca el proceso de lavado. Este proceso sincroniza el estado de su base de datos con el estado de su sesión al detectar cambios de estado y ejecutar las respectivas declaraciones SQL.

LennoxGER
fuente