【发布时间】:2012-10-04 10:24:34
【问题描述】:
我有以下情况:
2 名具有会话的 swingworkers 从数据库中收集数据。现在我想取消第二个 swingworker。我执行 swingworker.cancel(true) 并在 swingworker 的 done() 方法中使用 session.close() 关闭会话。
在我完成之后,我认为 swingworker 有一个正在执行的 sql 语句,但他被取消并且会话关闭,因此发生以下执行:
java.lang.NullPointerException
at org.hibernate.engine.jdbc.internal.proxy.ConnectionProxyHandler.getResourceRegistry(ConnectionProxyHandler.java:104)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.getResourceRegistry(AbstractStatementProxyHandler.java:73)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.wrapIfNecessary(AbstractStatementProxyHandler.java:150)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:123)
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
at $Proxy9.executeQuery(Unknown Source)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1953)
at org.hibernate.loader.Loader.scroll(Loader.java:2510)
at org.hibernate.loader.custom.CustomLoader.scroll(CustomLoader.java:337)
at org.hibernate.internal.SessionImpl.scrollCustomQuery(SessionImpl.java:1760)
at org.hibernate.internal.AbstractSessionImpl.scroll(AbstractSessionImpl.java:232)
at org.hibernate.internal.SQLQueryImpl.scroll(SQLQueryImpl.java:182)
at de.mudisar.dataloader.SecondarySwingWorker.doInBackground(SecondarySwingWorker.java:71)
at de.mudisar.dataloader.SecondarySwingWorker.doInBackground(SecondarySwingWorker.java:32)
at javax.swing.SwingWorker$1.call(SwingWorker.java:277)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at javax.swing.SwingWorker.run(SwingWorker.java:316)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
我能做些什么来解决这个问题。如果我取消 swingworker,我希望取消所有 sql 操作或其他操作,然后关闭会话。
//编辑:
这是我的 swingworker 代码。这个 swingworker 有自己的会话:
@Override
protected Void doInBackground() throws Exception {
doMappings();
fetchSQL();
}
private void fetchSQL(){
for(String str : map.keySet()){
//build sql;
SQLQuery q = sess.createSQLQuery(query).addEntity("ins", ALL_RSC_DATA.class);
q.setFetchSize(Integer.valueOf(1000));
q.setReadOnly(true);
ScrollableResults results = q.scroll(ScrollMode.FORWARD_ONLY);
while (results.next()) {
//processing
}
}
}
这是我处理用户输入的其他类的操作(用于取消 swingworker):
public Action cancelPrimarySwingWorker = new AbstractAction() {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent arg0) {
if(psw != null && !psw.isDone()){
closeDBConnection(psw.getSession());
psw.cancel(true);
psw = null;
restoreData();
}
}
};
关于这里的完整信息,我的 closeDBConnection() 代码:
@SuppressWarnings("deprecation")
public static void closeDBConnection(Session session) {
if(session != null){
try {
//session.connection().createStatement().execute("SHUTDOWN");
if(session.isOpen()){
session.cancelQuery();
session.clear();
session.close();
}
session = null;
}
catch (Exception sqle) {
logging(sqle);
System.exit(1);
}
}
}
【问题讨论】:
-
编辑您的帖子以包含
de.mudisar.dataloader.SecondarySwingWorker类的骨架,显示您如何捕获中断、取消查询和关闭会话。根据堆栈跟踪doInBackground()尚未完成,所以done()不应该被调用。没有看到你的代码,没有人可以帮助你。 -
抱歉,我无法发布任何代码。我的完整方法周围有一个 try catch 块。我使用 session.close 关闭会话并使用 session.cancelQuery 取消查询。抱歉,我无法显示代码。我希望我们在没有代码的情况下找到错误
-
您确定可以提取代码骨架并删除任何专有信息吗?如果没有,您可能需要靠自己。
-
我已经编辑了我的问题。我希望这会有所帮助
-
这无济于事:您需要做的是提取一个 SSCCE 来演示问题(模拟数据库访问)...
标签: java multithreading swing hibernate swingworker