Guarda transaccional sin llamar al método de actualización


Tengo un método anotado con @Transactional. Recupero un objeto de mi base de datos Oracle, cambio un campo y luego regreso del método. Olvidé guardar el objeto, pero descubrí que la base de datos se actualiza de todos modos.

ApplicationContext

<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

Mi método

@Transactional
public void myMethod(long id) {
    MyObject myObj = dao.getMstAttributeById(id);
    myObj.setName("new name");
    //dao.update(myObj);
}

Mi pregunta es ¿por qué myObject se mantiene en la base de datos?

Author: meriton, 2011-11-19

3 answers

Porque hibernate detectará automáticamente los cambios realizados en las entidades persistentes y actualizará la base de datos en consecuencia. Este comportamiento está documentado en capítulo 11 del manual de referencia de hibernación. La parte pertinente dice:

Hibernate define y soporta los siguientes estados de objeto:

  • Transient - un objeto es transitorio si acaba de ser instanciado usando el nuevo operador, y no está asociado con una hibernación Sesion. No tiene representación persistente en la base de datos y no se ha asignado ningún valor de identificador. Las instancias transitorias serán destruidas por el recolector de basura si la aplicación ya no tiene una referencia. Use la sesión Hibernate para hacer que un objeto sea persistente (y deje que Hibernate se encargue de las instrucciones SQL que deben ejecutarse para esta transición).

  • Persistent - una instancia persistente tiene una representación en la base de datos y un identificador valor. Es posible que solo se haya guardado o cargado, sin embargo, está por definición en el ámbito de una sesión. Hibernate detectará cualquier cambio realizado en un objeto en estado persistente y sincronizará el estado con la base de datos cuando se complete la unidad de trabajo. Los desarrolladores no ejecutan instrucciones de ACTUALIZACIÓN manual ni eliminan instrucciones cuando un objeto debe convertirse en transitorio.

  • Detached - una instancia detached es un objeto que ha sido persistente, pero su sesión ha sido cerrado. La referencia al objeto sigue siendo válida, por supuesto, y la instancia separada podría incluso modificarse en este estado. Una instancia separada se puede volver a unir a una nueva sesión en un momento posterior, lo que la hace (y todas las modificaciones) persistente de nuevo. Esta característica permite un modelo de programación para unidades de trabajo de larga duración que requieren tiempo de reflexión del usuario. Las llamamos transacciones de aplicación, es decir, una unidad de trabajo desde el punto de vista del usuario.

 50
Author: meriton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-19 00:51:02

Si está utilizando un JPA, entonces la especificación dice que si su Entidad está en estado administrado (y esto es lo que hace al obtener los datos del DAO dentro de una transacción activa), todos los cambios realizados en ella se reflejarán en la base de datos durante la transacción commit.

Entonces, en otras palabras - realmente no importa si invoca la operación update o no porque el commit de transacción vaciará los cambios en la base de datos.

 4
Author: Piotr Nowicki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-19 00:47:24

He encontrado que prevenir las actualizaciones automáticas de la base de datos es un proceso de dos pasos.

Paso I::

getSession().setFlushMode(FlushMode.MANUAL) // [FlushMode.NEVER is depracated in 4.x]

Paso II:

getSession().clear(); //This will actually discard all changes
 1
Author: Sagar Kapadia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-12 16:49:27