【发布时间】:2014-07-28 06:57:12
【问题描述】:
我有一个带有 Tomcat 的 Web 应用程序。我正在使用一些线程而不是在控制器中执行。在这个线程中,我执行其他线程。
这个线程需要与 Hibernate 进行会话,但是当我执行一些查询时它不起作用,尽管我在每个线程的“运行”方法中打开了一个新会话。
当我在 Tomcat 外部执行这段代码时,它就像一个简单的 java main 一样工作。所以,看起来我对Tomcat做错了。 我想这可能是因为 OpenSessionInViewFilter。我收到关于当前线程没有会话的错误。
我得到的例外是:
org.hibernate.HibernateException: No Session found for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:941)
我的 web.xml
<filter>
<filter-name>sessionView</filter-name>
<filter-class>
org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sessionView</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
我的控制器
@Override
protected ModelAndView onSubmit(final HttpServletRequest request,
final HttpServletResponse response, final Object command, final BindException errors)
throws Exception {
MyThread thread = new ExecuteETLThread();
thread.start();
...
}
我的线程:
public final class MyThread extends AbstracThread {
@Override
public void runThread() {
try {
//I get an exception here. I just put this senstence here for checking.
context.getConfigurationDAO().get("A");
//Normally, I open more threads here that they connect with hibernate and fail.
//otherThread.start();
} catch (final Exception e) {
LOG.error(e);
}
}
抽象线程:
public abstract class AbstractThread extends Thread {
@Override
public final void run() {
try {
OpenSessionInView.openSession();
runThread();
} catch (final Exception e) {
LOG.error("Error running BidoopThread", e);
} finally {
OpenSessionInView.closeSession();
}
}
public abstract void runThread();
}
使用 Hibernate 打开会话。
public final class OpenSessionInView {
public static void openSession() {
final SessionFactory sf = Factory.getSessionFactory();
final Session session = sf.openSession();
session.setFlushMode(FlushMode.COMMIT);
TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session));
}
public static void closeSession() {
final SessionFactory sf = Factory.getSessionFactory();
final SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.unbindResource(sf);
SessionFactoryUtils.closeSession(sessionHolder.getSession());
}
【问题讨论】:
-
为什么要对 JavaEE 应用程序进行多线程处理?这是您使用 Tomcat 免费获得的东西之一..
-
线程执行一些可能需要一段时间的 MapReduce 代码。所以,我不想让用户等待答案。有意义吗?
-
还有其他方法吗?
-
您可以使用
Spring和@Async注释来避免手动线程处理。另外,我认为有问题的错误通常与在没有事务上下文的情况下执行一些 JPA 调用有关。
标签: java multithreading hibernate tomcat