【发布时间】:2013-05-06 17:31:46
【问题描述】:
我在基于 Swing 的桌面应用程序中使用 JPA。这是我的代码的样子:
public Object methodA() {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
boolean hasError = false;
try {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// JPA operation does not work here
// because transaction has been committed!
}
});
...
return xXx;
} catch (Exception ex) {
hasError = true;
em.getTransaction().rollback();
} finally {
em.close();
if (!hasError) {
em.getTransaction().commit();
}
}
return null;
}
我将这个try - catch - finally 用于所有需要事务的方法。它按预期工作,但具有SwingUtilities.invokeLater() 的方法除外。
finally 将在新线程中的所有代码执行之前到达;因此,如果SwingUtilities.invokeLater()内部有JPA操作,则会因为事务已经提交而失败。
我是否可以遵循try - catch - finally 的通用用例以确保仅在执行所有代码(包括SwingUtilities.invokeLater() 中的代码)后才会提交事务?
【问题讨论】:
-
你为什么要使用
SwingUtilities.invokeLater来操作实体?该方法的重点是在您完成更新工作之后更新 gui。 -
我怕有一天我会在那里意外触发偷取。
-
延迟抓取是你真正的问题,所以努力解决它。您编写的代码与您应该使用 Swing 的方式完全相反。而且由于 EDT 线程永远不会完成直到您的程序退出,您对代码应该如何执行的基本假设是不正确的。
-
我打算使用 AOP 将这些 try-catch-finally 注入所有相关方法。我将尝试通过尽可能长时间保持 EntityManager 打开来解决延迟获取问题。即使代码不在事务内部(也许这不在 JPA 中?),Hibernate 也会执行延迟获取(延迟加载)。这样一来,延迟获取将在
SwingUtilities.invokeLater和 EDT 中工作。
标签: java jpa jpa-2.0 try-catch-finally try-finally