¿Hibernate vaciará mi objeto persistente actualizado al llamar a session.close () con FlushMode.AUTO?

Si FlushMode.AUTO está configurado, ¿Hibernate vaciará mi objeto persistente actualizado cuando llame a session.close ()?

Sé que session.close () normalmente no vacía la sesión, pero no estoy seguro de cómo FlushMode.AUTO afecta esto.

De los documentos:

FlushMode.AUTO
En ocasiones, la sesión se vacía antes de la ejecución de la consulta para garantizar que las consultas nunca devuelvan el estado obsoleto. Este es el modo de descarga predeterminado.

¿Esto significa que puedo confiar en Hibernate para verificar que mis cambios se vacíen a veces antes de que mi sesión se cierre?

Ejemplo de código pequeño:

Session session = HibernateSessionFactory.getSession(); PersistedObject p = session.get(PersistedObject.class,id); p.setSomeProperty(newValue); session.close(); 

ACTUALIZAR
De acuerdo con los documentos, estos son los lugares donde se vaciará la sesión (cuando se usa AUTO)

  • antes de algunas ejecuciones de consultas
  • de org.hibernate.Transaction.commit ()
  • de Session.flush ()

Esto no dice nada sobre Session.close ()

¿Hibernate vaciará mi objeto persistente actualizado al llamar a session.close () (usando FlushMode.AUTO)?

No, no lo hará, y debe usar una transacción con límites bien definidos . Citando el acceso a datos no transaccionales y el modo autocompromiso :

Trabajando de forma no transaccional con Hibernate

Mire el siguiente código, que accede a la base de datos sin límites de transacción:

 Session session = sessionFactory.openSession(); session.get(Item.class, 123l); session.close(); 

De forma predeterminada, en un entorno Java SE con una configuración JDBC, esto es lo que sucede si ejecuta este fragmento de código:

  1. Se abre una nueva sesión. No obtiene una conexión de base de datos en este punto.
  2. La llamada a get () desencadena un SQL SELECT. La sesión ahora obtiene una conexión JDBC desde el grupo de conexiones. Hibernate, de forma predeterminada, desactiva inmediatamente el modo de confirmación automática en esta conexión con setAutoCommit (falso). Esto efectivamente inicia una transacción JDBC!
  3. El SELECCIONAR se ejecuta dentro de esta transacción JDBC. La sesión se cierra y la conexión se devuelve al grupo y es liberada por Hibernate: Hibernate llama a close () en la conexión JDBC. ¿Qué pasa con la transacción no confirmada?

La respuesta a esa pregunta es: “¡Depende!” La especificación JDBC no dice nada sobre las transacciones pendientes cuando se llama a close () en una conexión. Lo que sucede depende de cómo los proveedores implementan la especificación. Con los controladores Oracle JDBC, por ejemplo, la llamada a close () confirma la transacción. La mayoría de los otros proveedores de JDBC toman la ruta correcta y retrotraen cualquier transacción pendiente cuando el objeto de Conexión JDBC se cierra y el recurso se devuelve al grupo.

Obviamente, esto no será un problema para el SELECT que ha ejecutado, pero observe esta variación:

 Session session = getSessionFactory().openSession(); Long generatedId = session.save(item); session.close(); 

Este código da como resultado una instrucción INSERT, ejecutada dentro de una transacción que nunca se compromete o retrotrae. En Oracle, este fragmento de código inserta datos permanentemente; en otras bases de datos, puede que no. (Esta situación es un poco más complicada: el INSERT se ejecuta solo si el generador de identificador lo requiere. Por ejemplo, se puede obtener un valor de identificador de una secuencia sin un INSERT. La entidad persistente se pone en cola hasta la inserción en tiempo real, que nunca sucede en este código . Una estrategia de identidad requiere un INSERT inmediato para que se genere el valor).

En pocas palabras: use la demarcación de transacción explícita.

al cerrar una sesión, siempre se descargará todo el trabajo a la base de datos. Flushmode.AUTO descarga trabajos a la base de datos cuando hay cambios y está haciendo clic en la tabla con registros modificados.