2011-01-26 18 views
5

Estoy jugando con Spring + Hibernate y gestión de transacciones "manual" con PostgreSQL Me gustaría probar esto y entender cómo funciona esto antes de pasar a la administración de transacciones basada en aop.HibernateDaoSupport, la transacción no se ha retrotraído

@Repository 
public class UserDAOImpl extends HibernateDaoSupport implements UserDAO { 

    @Override 
    public void saveUser(User u) { 
     Transaction tx = getSession().beginTransaction(); 
     getHibernateTemplate().saveOrUpdate(u); 
     tx.rollback(); 

    } 
} 

Llamando saveUser aquí, supongo que al guardar un nuevo usuario se revertirá. Sin embargo, al pasar a una línea de comando psql, el usuario se guarda en la tabla.

¿Por qué no se revierte? ¿Qué tengo que configurar para hacer transacciones de esta manera?

Editar; un poco más la depuración parece indicar getHibernateTemplate() utiliza una sesión diferente de lo getSession() devuelve (?)

Cambiar el código para

Transaction tx = getSession().beginTransaction(); 
getSession().persist(u); 
tx.rollback(); 

y la transacción se pone deshacerse. Pero todavía no entiendo por qué la HibernateTemplate usaría/crear una nueva sesión ..

Respuesta

2

Un par de posibilidades vienen a la mente (sin doble sentido):

a) Sus valores predeterminados del controlador JDBC de confirmación automática = true y de alguna manera ignora las llamadas beginTransaction() y rollback();

b) Si está utilizando Spring 3, I crea que SessionFactory.getSession() devuelve el objeto de sesión de Hibernate envuelto por un proxy de Spring. El proxy de Spring está configurado en la sesión en parte para manejar la gestión de transacciones, y ¿es posible que esté interfiriendo con sus llamadas de transacciones manuales?

Si bien es cierto que puede usar los proxies con ámbito AOP para la gestión de transacciones, ¿por qué no utilizar la anotación @Transactional (readOnly = false | true) en los métodos de su capa de servicio? En el archivo de configuración de primavera para sus métodos capa de servicio, todo lo que hay que hacer para que esto funcione es agregar

<tx:annotation-driven /> 

véanse los capítulos 10 y 13 de la Documentación muelle de referencia en gestión de transacciones y ORM de acceso a datos, respectivamente:

http://static.springsource.org/spring/docs/3.0.x/reference/index.html

por último, si usted está utilizando Spring 3, puede eliminar las referencias a la Spring Framework en su código mediante la inyección del frijol SessionFactory primavera-proxy en su código DAO - no hay necesidad de utilizar HibernateDaoSupport. Simplemente inyecte SessionFactory, obtenga la sesión actual y use Hibernate de acuerdo con los ejemplos de Hibernate. (Puede combinar HibernateDaoSupport y código de Hibernate simple basado en SessionFactory en la misma aplicación, si es necesario.)

+0

La última parte de esto ya se ha solucionado. Quiero entender esto * antes * de entrar en AOP o transacciones basadas en anotaciones. – Anonym

+0

b) es el único culpable en el que puedo pensar a partir de ahora. Es decir. hay un foo mágico pasando. Al final me salté la parte completa y me fui con la sugerencia de la gestión de transacciones basada en anotaciones AOP, deshaciéndose de HibernateDaoSupport e inyectando un LocalSessionFactoryBean directamente en el DAO. Funciona bien. – Anonym

2

Si ve el JavaDoc para HibernateDaoSupport.getSession(), indica que obtendrá una nueva sesión o le dará la eso es utilizado por la transacción existente. En su caso, ya no hay una transacción en la lista con HibernateDaoSupport.

Así que si usa getHibernateTemplate(). GetSession() en lugar de solo getSession(), debería obtener la sesión que utiliza HibernateTemplate y luego debería funcionar lo anterior.

Hágame saber cómo va esto.

EDIT:

estoy de acuerdo su protegida ... mi mal. Entonces, la otra opción es mantener enlazado el hilo de la sesión, que generalmente es la mejor práctica en una aplicación web. Si HibernateDaoSupport va a encontrar una sesión enlazada al hilo, no creará una nueva y usará la misma. Eso debería permitirle hacer retrocesos.

+0

Probablemente haya identificado el motivo, aunque getSession() está protegido en HibernateTemplet, por lo que no puedo obtener esa sesión. – Anonym

+0

@Anonym, intente habilitar el registro de depuración para las categorías org.springframework y org.hibernate para ver lo que sucede bajo el capó. –

Cuestiones relacionadas