【发布时间】:2018-07-02 13:46:55
【问题描述】:
我需要在单个 DAO 类中使用 2 个不同的数据库。其中一个数据库是读/写的,而另一个是只读的。
我为这些数据库创建了 2 个数据源、2 个会话工厂和 2 个事务管理器(读/写数据库的事务管理器是平台事务管理器)。我在服务方法上使用@Transactional 来配置Spring 进行事务管理。
当我们在 DAO 类中调用 sessionFactory.getCurrentSession() 时,我们得到随机 Session is closed! 异常(我不能总是生成它,它有时可以正常工作,有时会出错):
org.hibernate.SessionException: Session is closed!
at org.hibernate.internal.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:133)
at org.hibernate.internal.SessionImpl.setFlushMode(SessionImpl.java:1435)
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:99)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
我不需要使用全局事务 (XA),我只想查询 2 个不同的数据库。
我已经阅读了这个帖子,它建议像我们现在一样在 DAO 层中注入两个单独的会话工厂:Session factories to handle multiple DB connections
根据这个答案,AbstractRoutingDataSource 也不适用于单个 Dao 类:https://stackoverflow.com/a/7379048/572380
我的 dao 中的示例代码如下所示:
Criteria criteria = sessionFactory1.getCurrentSession().createCriteria(MyClass.class);
criteria.add(Restrictions.eq("id", id));
criteria.list();
criteria = sessionFactory2.getCurrentSession().createCriteria(MyClass2.class); // generates random "Session is closed!" error.
criteria.add(Restrictions.eq("id", id));
criteria.list();
我也尝试过使用“doInHibernate”方法。但是传递给它的会话也随机抛出“会话已关闭!”例外:
@Autowired
protected HibernateTemplate hibernateTemplate;
@SuppressWarnings("unchecked")
protected List<Map<String, Object>> executeStaticQuery(final String sql) {
HibernateCallback<List<Map<String, Object>>> hibernateCallback = new HibernateCallback<List<Map<String, Object>>>() {
@Override
public List<Map<String, Object>> doInHibernate(Session session) throws HibernateException {
SQLQuery query = session.createSQLQuery(sql);
query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
return query.list();
}
};
return hibernateTemplate.execute(hibernateCallback);
}
【问题讨论】:
-
你能发布你的代码吗?为什么不使用注入两个 DAO 的单一事务服务?出于兴趣,您为什么要调用 getCurrentSession() ?
-
@PaulNUK 我已经用我的代码更新了这个问题。您所说的“拥有注入两个 DAO 的单一事务服务”是什么意思?我有 2 个数据库,所以我需要 2 个事务或 1 个全局事务。 XA 很难实现,在这种情况下不需要。
标签: java spring hibernate session dao