会话管理在*多线程* Swing应用程序中使用Hibernate [英] Session management using Hibernate in a *multi-threaded* Swing application

查看:74
本文介绍了会话管理在*多线程* Swing应用程序中使用Hibernate的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在开发一个Swing应用程序,该应用程序的性质需要是多线程的(相当大)。几乎所有的用户交互都可能通过互联网从某些远程服务器获取数据,因为我既不控制这些服务器,也不控制互联网本身,因此响应时间过长是不可避免的。当EDT忙时,Swing UI显然无法重新绘制,所以所有远程服务器调用都需要由后台线程执行。



我的问题:



由后台线程获取的数据通过本地(内存中)数据库(远程服务器返回本地数据库中数据的ID /引用)中的数据获得'丰富'。这些数据最终会传递到EDT,并成为视图模型的一部分。一些实体在这个时候还没有完全初始化(启用了延迟获取),因此用户可能会触发延迟获取。在JTable中滚动。由于hibernate会话已经关闭,这将触发LazyInitializationException。我无法知道用户何时可能触发延迟提取,因此按需创建会话/附加分离的对象在这里不起作用。



我'已解决'这个问题是由于:


  • 使用一个(同步的,因为Session实例不是线程安全的)整个应用程序的会话

  • 完全禁用延迟获取



虽然这样做有效,但应用程序的性能却受到很大影响(有时接近不可用)。减速主要是由每个查询现在获取的大量对象造成的。



我目前正在考虑将应用程序的设计更改为'Session-per-线程'并将由非EDT线程获取的所有实体迁移到EDT线程的会话中(类似于

附注:与数据库更新相关的任何问题都不适用,因为所有数据库实体是只读的(引用数据)。



有关如何在此场景中使用Hibernate 延迟加载的其他想法?

解决方案

不要将会话本身暴露在您的数据API中。你仍然可以懒惰地做,只要确保每次从 '数据'线程完成水合作用。你可以使用一个块(runnable或某种类型的命令类,可能是最好的Java在这里可以为你做的最好的),它由代码执行,从'数据'线程执行加载异步。当你在UI代码中时,(当然在UI线程上)字段的某种'数据准备好'事件由数据服务发布。然后,您可以从UI中的事件使用中获取数据。


I'm currently working on a (rather large) pet project of mine , a Swing application that by it's very nature needs to be multi-threaded. Almost all user interactions might fetch data from some remote servers over the internet , since I neither control these servers nor the internet itself, long response times are thus inevitable. A Swing UI obviously cannot repaint itself while the EDT is busy so all remote server calls need to be executed by background thread(s).

My problem:

Data fetched by the background threads gets 'enriched' with data from a local (in-memory) database (remote server returns IDs/references to data in the local database). This data later eventually gets passed to the EDT where it becomes part of the view model. Some entities are not completely initialized at this point (lazy-fetching enabled) so the user might trigger lazy-fetching by e.g. scrolling in a JTable. Since the hibernate session is already closed this will trigger a LazyInitializationException. I can't know when lazy-fetching might be triggered by the user so creating a session on demand/attaching the detached object will not work here.

I 'solved' this problem by:

  • using a single (synchronized , since Session instances are not thread-safe) Session for the whole application
  • disabling lazy-fetching completely

While this works, the application's performance has suffered greatly (sometimes being close to unusable). The slowdown is mainly caused by the large number of objects that are now fetched by each query.

I'm currently thinking about changing the application's design to 'Session-per-thread' and migrating all entities fetched by non-EDT threads to the EDT thread's Session (similar to this posting on the Hibernate forums).

Side-note: Any problems related to database updates do not apply since all database entities are read-only (reference data).

Any other ideas on how to use Hibernate with lazy-loading in this scenario ?

解决方案

Don't expose the Session itself in your data API. You can still do it lazily, just make sure that the hydration is being done from the 'data' thread each time. You could use a block (runnable or some kind of command class is probably the best Java can do for you here unfortunately) that's wrapped by code that performs the load async from the 'data' thread. When you're in UI code, (on the UI thread of course) field some kind of a 'data is ready' event that is posted by the data service. You can then get the data from the event use in the UI.

这篇关于会话管理在*多线程* Swing应用程序中使用Hibernate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆