HIbernate commit () y flush ()

Busqué en Google y leí mucho sobre org.hibernate.Transaction.commit() y org.hibernate.Session.flush() , conozco el propósito de cada método, pero todavía tengo una pregunta.

¿Es una buena práctica llamar a método org.hibernate.Session.flush() a mano? Como se dijo en org.hibernate.Session docs,

Debe llamarse al final de una unidad de trabajo, antes de comprometer la transacción y cerrar la sesión (dependiendo del modo de descarga, Transaction.commit () llama a este método).

¿Podría explicarme el propósito de llamar a org.hibernate.Session.flush() manualmente si org.hibernate.Transaction.commit() lo llamará automáticamente?

¡Gracias!

En el Manual de Hibernate puedes ver este ejemplo

 Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); for ( int i=0; i<100000; i++ ) { Customer customer = new Customer(.....); session.save(customer); if ( i % 20 == 0 ) { //20, same as the JDBC batch size //flush a batch of inserts and release memory: session.flush(); session.clear(); } } tx.commit(); session.close(); 

Sin la llamada al método de descarga, su caché de primer nivel arrojaría una OutOfMemoryException

También puedes ver esta publicación sobre el enjuague

Un caso común para el lavado explícito es cuando se crea una nueva entidad persistente y se desea que tenga una clave primaria artificial generada y asignada a ella, para que pueda usarla más adelante en la misma transacción. En ese caso, llamar a Flush daría como resultado que a su entidad se le dé una identificación.

Otro caso es si hay muchas cosas en la memoria caché de primer nivel y desea eliminarlas periódicamente (para reducir la cantidad de memoria utilizada por la memoria caché) pero aún desea comprometer todo el conjunto . Este es el caso que cubre la respuesta de Aleksei (+1 de mí).

flush() sincronizará su base de datos con el estado actual de los objetos / objetos contenidos en la memoria, pero no confirmará la transacción. Por lo tanto, si obtiene una excepción después de llamar a flush() , la transacción se retrotraerá. Puede sincronizar su base de datos con pequeños fragmentos de datos usando flush() lugar de comprometer una gran cantidad de datos a la vez utilizando commit() y se corre el riesgo de obtener una Excepción de falta de memoria .

commit() hará que los datos almacenados en la base de datos sean permanentes. No hay forma de que pueda deshacer su transacción una vez que commit() tenga éxito.

enjuagar(); Flushing es el proceso de sincronización de la tienda persistente subyacente con estado persistente mantenido en la memoria. Se actualizará o insertará en sus tablas en la transacción en ejecución, pero es posible que no confirme esos cambios.

Necesita enjuagar en el procesamiento por lotes, de lo contrario puede dar OutOfMemoryException.

Cometer(); Commit hará que la base de datos se comprometa. Cuando tienes un objeto persistente y cambias un valor en él, se ensucia e hibernadamente necesita enjuagar estos cambios en tu capa de persistencia. Así que debes confirmar pero también termina la unidad de trabajo. transaction.commit ()

Por defecto, el modo lavado es AUTO, lo que significa que: “La sesión a veces se vacía antes de la ejecución de la consulta para garantizar que las consultas nunca devuelvan el estado obsoleto”, pero la mayor parte del tiempo se vacía al confirmar los cambios. La llamada manual del método de descarga es útil cuando utiliza FlushMode = MANUAL o si desea realizar algún tipo de optimización. Pero nunca he hecho esto, así que no puedo darte consejos prácticos.

Por lo general, no se recomienda llamar a color explícitamente a menos que sea necesario. Por lo general, Hibernate llama automáticamente a Flush al final de la transacción y deberíamos dejar que funcione. Ahora, hay algunos casos en los que es posible que deba llamar explícitamente a flush donde una segunda tarea depende del resultado de la primera tarea de persistencia, ambas dentro de la misma transacción.

Por ejemplo, puede que necesite persistir una nueva entidad y luego usar el Id de esa entidad para hacer otra tarea dentro de la misma transacción, en ese caso se requiere primero purgar la entidad de manera explícita.

 @Transactional void someServiceMethod(Entity entity){ em.persist(entity); em.flush() //need to explicitly flush in order to use id in next statement doSomeThingElse(entity.getId()); } 

También tenga en cuenta que, el enjuague explícito no causa una confirmación de la base de datos, una confirmación de la base de datos se realiza solo al final de una transacción, por lo que si se produce algún error en el tiempo de ejecución después de realizar la descarga, los cambios seguirán revertidos.

session.flush () es un método de sincronización para insertar datos en la base de datos secuencialmente. Si usamos este método, los datos no se almacenarán en la base de datos, pero se almacenarán en la memoria caché; si se produce alguna excepción, podemos manejarla. Pero commit () almacenará datos en la base de datos, si almacenamos más cantidad de datos, puede haber posibilidad de salir de la excepción de memoria, como en el progtwig JDBC en el tema Guardar punto