我目前正在开发我的一个(相当大的)宠物项目,这是一个Swing应用程序,它本质上需要多线程。几乎所有用户交互都可能通过Internet从某些远程服务器获取数据,因为我既不能控制这些服务器,也不能控制Internet本身,因此不可避免的是需要较长的响应时间。EDT忙时,Swing UI显然无法重绘自身,因此所有远程服务器调用都需要由后台线程执行。
我的问题:
后台线程获取的数据被本地(内存)数据库中的数据“丰富”(远程服务器返回对本地数据库中数据的ID /引用)。最终,这些数据将传递到EDT,并成为视图模型的一部分。某些实体此时尚未完全初始化(启用了延迟提取),因此用户可能会通过例如滚动JTable来触发延迟提取。由于hibernate会话已关闭,因此将触发LazyInitializationException。我不知道用户何时可能触发延迟获取,因此按需创建会话/附加分离的对象在这里不起作用。
我通过以下方式“解决”了这个问题:
在这种情况下,应用程序的性能受到了极大的损害(有时接近无法使用)。速度下降主要是由于每个查询现在获取的对象过多。
我目前正在考虑将应用程序的设计更改为“每线程会话”,并将非EDT线程获取的所有实体迁移到EDT线程的Session(类似于Hibernate论坛上的此帖子)。
旁注:与数据库更新有关的任何问题都不适用,因为所有数据库实体都是只读的(参考数据)。
关于在这种情况下如何将Hibernate 与 延迟加载一起使用的其他想法?
不要在数据API中公开会话本身。您仍然可以懒惰地执行此操作,只需确保每次都 在 “数据”线程中进行水化处理。您可以使用一个代码块(可运行的或某种命令类可能是Java可以在这里为您提供最好的Java功能),该代码块由执行“数据”线程异步加载的代码所包装。当您使用UI代码时,(当然在UI线程上)字段会由数据服务发布某种“数据就绪”事件。然后,您可以从UI中的事件使用中获取数据。