Respuestas:
Vaciar la sesión fuerza a Hibernate a sincronizar el estado en memoria del Session
con la base de datos (es decir, escribir cambios en la base de datos). De forma predeterminada, Hibernate eliminará los cambios automáticamente:
Permitir vaciar explícitamente Session
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, ...).
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?
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.
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.
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()
.
Puede usar flush
para 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 commit
sea 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.
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 )
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
EntityManager
y el HibernateSession
exponen 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
,UPDATE
oDELETE
.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 (
AUTO
yCOMMIT
), 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 llamarSession.flush()
explícitamente para aplicar los cambios de contexto de persistencia.De forma predeterminada, Hibernate usa el
AUTO
modo 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.
Llamar EntityManager#flush
tiene 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.