在使用SessionFactory.getCurrentSession进行hibernate操作的时候,遇到org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here的错误,
查看spring源码:
private static Session doGetSession(
SessionFactory sessionFactory, Interceptor entityInterceptor,
SQLExceptionTranslator jdbcExceptionTranslator, boolean allowCreate)
throws HibernateException, IllegalStateException {
Assert.notNull(sessionFactory, "No SessionFactory specified");
SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
if (sessionHolder != null && !sessionHolder.isEmpty()) {
// pre-bound Hibernate Session
Session session = null;
if (TransactionSynchronizationManager.isSynchronizationActive() &&
sessionHolder.doesNotHoldNonDefaultSession()) {
// Spring transaction management is active ->
// register pre-bound Session with it for transactional flushing.
session = sessionHolder.getValidatedSession();
if (session != null && !sessionHolder.isSynchronizedWithTransaction()) {
logger.debug("Registering Spring transaction synchronization for existing Hibernate Session");
TransactionSynchronizationManager.registerSynchronization(
new SpringSessionSynchronization(sessionHolder, sessionFactory, jdbcExceptionTranslator, false));
sessionHolder.setSynchronizedWithTransaction(true);
// Switch to FlushMode.AUTO, as we have to assume a thread-bound Session
// with FlushMode.NEVER, which needs to allow flushing within the transaction.
FlushMode flushMode = session.getFlushMode();
if (flushMode.lessThan(FlushMode.COMMIT) &&
!TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
session.setFlushMode(FlushMode.AUTO);
sessionHolder.setPreviousFlushMode(flushMode);
}
}
}
else {
// No Spring transaction management active -> try JTA transaction synchronization.
session = getJtaSynchronizedSession(sessionHolder, sessionFactory, jdbcExceptionTranslator);
}
if (session != null) {
return session;
}
}
logger.debug("Opening Hibernate Session");
Session session = (entityInterceptor != null ?
sessionFactory.openSession(entityInterceptor) : sessionFactory.openSession());
// Use same Session for further Hibernate actions within the transaction.
// Thread object will get removed by synchronization at transaction completion.
if (TransactionSynchronizationManager.isSynchronizationActive()) {
// We're within a Spring-managed transaction, possibly from JtaTransactionManager.
logger.debug("Registering Spring transaction synchronization for new Hibernate Session");
SessionHolder holderToUse = sessionHolder;
if (holderToUse == null) {
holderToUse = new SessionHolder(session);
}
else {
holderToUse.addSession(session);
}
if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
session.setFlushMode(FlushMode.NEVER);
}
TransactionSynchronizationManager.registerSynchronization(
new SpringSessionSynchronization(holderToUse, sessionFactory, jdbcExceptionTranslator, true));
holderToUse.setSynchronizedWithTransaction(true);
if (holderToUse != sessionHolder) {
TransactionSynchronizationManager.bindResource(sessionFactory, holderToUse);
}
}
else {
// No Spring transaction management active -> try JTA transaction synchronization.
registerJtaSynchronization(session, sessionFactory, jdbcExceptionTranslator, sessionHolder);
}
// Check whether we are allowed to return the Session.
if (!allowCreate && !isSessionTransactional(session, sessionFactory)) {
closeSession(session);
throw new IllegalStateException("No Hibernate Session bound to thread, " +
"and configuration does not allow creation of non-transactional one here");
}
return session;
}
然后在查看日志会发现session在打开后马上close了,从上面的代码中不难看出,session必须存在于某个transation中,仔细检查你的配置,应该不难找出问题了。
在spring2.5中用AbstractTransactionalJUnit4SpringContextTests进行TU测试的时候很难发现这个问题,因为他本身会打开一个stransaction
分享到:
相关推荐
理解 `SessionFactory.getCurrentSession()` 和 `Session.openSession()` 的区别对于优化和正确使用Hibernate至关重要。 首先,`SessionFactory` 是Hibernate中的一个接口,它是一个全局的、线程安全的工厂类,用于...
标题提到的"新Hibernate SessionFactory().getCurrentSession()猫腻"揭示了一个常见的使用误区或者说是陷阱,即不正确地使用SessionFactory的getCurrentSession()方法。这篇文章可能探讨了这个方法在实际应用中的...
随着Hibernate的更新,特别是SessionFactory.getCurrentSession()的出现,可以直接在Spring的事务范围内获取和管理Session,使得直接使用HibernateAPI成为可能。 2. **使用SessionFactory.getCurrentSession()** ...
Session session = sessionFactory.getCurrentSession(); session.save(user); } public void updateUser(User user) { Session session = sessionFactory.getCurrentSession(); session.update(user); } ...
Session session = sessionFactory.getCurrentSession(); session.save(book); } @Override @Transactional public void delete(String ISBN) { Session session = sessionFactory.getCurrentSession(); ...
Session session = sessionFactory.getCurrentSession(); session.save(user); } } ``` #### 2. 查询(Read) 查询操作涉及从数据库中获取数据并展示给用户。根据需求的不同,查询可以分为单一记录查询和多记录...
return (T) sessionFactory.getCurrentSession().get(clazz, id); } public void update(T entity) { Session session = sessionFactory.getCurrentSession(); session.update(entity); } public void ...
Session session = sessionFactory.getCurrentSession(); session.save(user); } } ``` 删(Delete):删除操作通常根据主键(通常是ID)来定位对象,然后调用Session的delete()方法。例如: ```java public ...
sessionFactory.getCurrentSession().save(new User()); // int a = 1 / 0; // 这行会抛异常 sessionFactory.getCurrentSession().save(new User()); } } 2,单元测试 @Test // ...
Session session = sessionFactory.getCurrentSession(); // 数据库操作 session.save(user); } } ``` 在这个例子中,`@Transactional`注解由Spring管理事务,Hibernate的`getCurrentSession()`会在需要时提供...
} // 添加方法 public void addJob(JobsDemo job) { // 获得连接对象 session = HibernateSessionFactory.getCurrentSession(); // 开始事务 tr = session.beginTransaction(); // 保存对象 session.save(job); // ...
Session session = sessionFactory.getCurrentSession(); return (User) session.get(User.class, id); } @Override public void addUser(User user) { Session session = sessionFactory.getCurrentSession...
Query q = this.sessionFactory.getCurrentSession().createQuery("from User where UId=?"); q.setParameter(0, uid); User u = (User) q.uniqueResult(); // 获取User对象 Set<Resource> resources = u....
return sessionFactory.getCurrentSession().get(User.class, id); } // 更新和删除操作类似,使用session的update和delete方法 ... } ``` 这里,`@Repository`注解表明这是一个Spring的DAO组件,`@Autowired`...
Session session = HibernateSessionFactory.getCurrentSession(); Query q = session.createQuery("from City"); q.setCacheable(true); return q.list(); Session session = HibernateSessionFactory....
return (User) sessionFactory.getCurrentSession().get(User.class, id); } ... } ``` Spring会自动将SessionFactory注入到Repository中,无需手动创建Session。在上述代码中,`getCurrentSession()`返回了一个...