一个事务中的Hibernate和JDBC
我有一个标记为@Transactional的方法。 它由几个函数组成,其中一个使用JDBC,第二个是Hibernate,第三个是JDBC。 问题是Hibernate函数所做的更改在最后一个与JDBC一起使用的函数中是不可见的。
@Transactional void update() { jdbcUpdate1(); hibernateupdate1(); jdbcUpdate2(); // results of hibernateupdate1() are not visible here }
所有函数都配置为使用相同的数据源:
myDataSource bean用于代码中。 myDataSource.getConnection()用于处理jdbc函数和中的连接
getHibernateTemplate().execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { ... } });
用于hibernate函数。 谢谢。
首先,避免在使用hibernate时使用JDBC。
然后,如果您真的需要它,请使用Session.doWork(..)
。 如果你的hibernate版本还没有这个方法,请从session.connection()
获取Connection
。
如果使用正确的Spring设置,则可以在同一事务中使用JDBC和Hibernate:
PROPAGATION_SUPPORTS,readOnly PROPAGATION_REQUIRED
这假设您的DAO的JDBC部分使用JdbcTemplate。 如果没有,你有几个选择:
- 使用DataSourceUtils.getConnection(javax.sql.DataSource)获取连接
- 使用TransactionAwareDataSourceProxy将传递给您的DAO的数据源(但不一定是传递给SessionFactory的数据源)包装起来
后者是首选,因为它隐藏了代理数据源中的DataSourceUtils.getConnection。
这当然是XML路径,应该很容易将其转换为基于注释。
问题是,Hibernate引擎上的操作不会导致立即执行SQL。 你可以在Hibernate会话上手动调用flush
来触发它。 然后,在同一事务中,SQL代码可以看到在hibernate中所做的更改。 只要你做DataSourceUtils.getConnection
来获得SQL连接,因为只有这样你才能让他们在同一个事务中运行…
在相反的方向上,这更棘手,因为你有一级缓存(会话缓存),也可能是二级缓存。 对于二级缓存,如果缓存行,则对Hibernate的所有更改都将对Hibernate不可见,直到缓存过期。
- Hibernate Criteria – 返回列不同的记录
- 注入自动连接的依赖项失败; 嵌套exception是org.springframework.beans.factory.BeanCreationException:
- 如何使用Hibernate JPA线程安全进行数据库访问?
- sessionfactory.openSession()和sessionfactory.openStatelessSession()之间的区别?
- 通过服务API公开Hibernate标准
- 什么是Hibernate中的transaction.commit()?
- 解决了在hibernate中收集依赖对象的限制
- 如何在多对多关系中使用hibernate和JPA删除孤立实体?
- 如何在Hibernate中进行SELECT查询包括子查询COUNT(*)