如何避免在Swing桌面应用程序中使用JPA延迟加载来阻止EDT

Cra*_*ger 12 java swing jpa desktop-application lazy-loading

我正在努力在Swing桌面应用程序中实际使用JPA(Hibernate,EclipseLink等).

JPA似乎是一个好主意,但依赖于延迟加载以提高效率.延迟加载需要实体管理器在实体bean的生命周期中存在,并且无法控制用于加载的线程或在EDT开始使用其他东西时在后台进行加载的任何方式.访问恰好在EDT上延迟加载的属性将阻止应用程序在数据库访问时使用UI,甚至无法设置忙碌光标.如果应用程序在wifi/3G或慢速上网运行,可能会让它看起来像已经崩溃.

为了避免延迟加载停止EDT,我必须使用分离的实体.然后,如果我真的需要一个惰性属性的值,我所有的组件(甚至应该是那些应该不知道数据库的组件)必须准备好处理延迟加载异常或使用PersistenceUtil来测试属性状态.他们必须将实体分派回要合并的数据库工作线程,并在分离并再次返回之前加载属性.

为了提高效率,我的组件需要事先知道需要bean的哪些属性.

因此,您将看到所有这些闪亮的教程演示如何使用JPA在NetBeans平台,Eclipse RCP,Swing App Framework等上创建一个简单的CRUD应用程序,但实际上这些方法违反了基本的Swing实践(不要阻止) EDT)并且在现实世界中完全不可行.

(更多细节请写在这里:http://soapyfrogs.blogspot.com/2010/07/jpa-and-hibernateeclipselinkopenjpaetc.html)

有一些相关的问题有一些有用的响应,但它们都没有真正涵盖edt阻塞/延迟加载/实体管理器生命周期管理问题.

远程病例中的Lazy/Eager加载策略(JPA)

别人怎么解决这个问题?我是否试图在桌面应用程序中使用JPA来吠叫错误的树?或者我有没有明显的解决方案?在使用JPA进行透明数据库访问时,您是如何避免阻止EDT并保持应用程序响应的?

tra*_*god 6

我只使用了带有嵌入式数据库的JPA,其中EDT上的延迟不是问题.在JDBC上下文中,我曾经使用SwingWorkerGUI通知来处理后台处理.我没有尝试使用JPA,但这是一个简单的JDBC 示例.

附录:感谢@Ash提到这个SwingWorkerbug.解决方法是从源代码构建提交.

  • 作为参考,来自JDK6u17的Sun/Oracle JVM中的SwingWorker版本显然有一个相当大的错误:http://bugs.sun.com/bugdatabase/view_bug.do?video_id = 6880336.评论结束时有一些解决方法. (3认同)

Rus*_*ard 3

我也遇到过同样的问题。我的解决方案是禁用延迟加载并确保所有实体在从数据库层返回之前都已完全初始化。这意味着您需要仔细设计实体,以便可以分块加载它们。您必须限制x对多关联的数量,否则您最终会在每次获取时检索一半的数据库。

我不知道这是否是最好的解决方案,但它确实有效。JPA 主要是为请求-响应无状态应用程序而设计的。它在有状态的 Swing 应用程序中仍然非常有用 - 它使您的程序可移植到多个数据库并节省大量样板代码。但是,在该环境中使用它必须更加小心。