Session management using Hibernate in a Swing application

前端 未结 4 1822
天涯浪人
天涯浪人 2020-12-23 23:46

How do you do your Hibernate session management in a Java Desktop Swing application? Do you use a single session? Multiple sessions?

Here are a few references on the

相关标签:
4条回答
  • 2020-12-24 00:20

    Use one session per thread (doc) and a version or timestamp column to allow optimistic concurrency and thereby avoiding session-to-instance conflicts. Attach instances to session when needed unless you need long running transactions or a restrictive isolation level.

    0 讨论(0)
  • 2020-12-24 00:22

    Problem with "''session per thread''" is good Swing applications do the database access outside the EDT, usually in newly created SwingWorker threads. This way, "''session per thread''" quickly becomes "''session per click''".

    0 讨论(0)
  • 2020-12-24 00:33

    Don't use a single session. For everything but the smallest applications, it will grow, collecting outdated data and become slower and slower, since the dirty check needs to check every entity in the session.

    If you don't need/want lazy loading and tracking of changes by Hibernate, you can use short-lived sessions.

    But if you want to benefit from the power of Hibernate use the approach I described in my blog: http://blog.schauderhaft.de/2008/09/28/hibernate-sessions-in-two-tier-rich-client-applications/

    or in the German version:

    http://blog.schauderhaft.de/2007/12/17/hibernate-sessions-in-fat-client-anwendungen/

    AFAIK it is really the same approach described in the http://in.relation.to/Bloggers/HibernateAndSwingDemoApp but with a recommendation how to actually scope your session: On Session per Frame, with the exception of modal Frames which use the session of the parent Frame.

    Just make sure never to combine objects from different sessions. It will cause lots of trouble.

    In reply to Vladimirs update:

    • The cancel actually works extremely nice with my approach: throw away the session.
    • session.flush does not fix the problem of the evergrowing session when you work with a single session for the application. Of course with the approach, you describe you can work with short-lived sessions which should work ok. BUT
    • you lose a lot: lazy loading only works with attached objects, automatic detection of dirty objects. If you work with detached objects (or objects that aren't entities at all) you have to do this yourself.
    0 讨论(0)
  • 2020-12-24 00:37

    Single session. Start transaction when you need to do a set of operations (like update data after dialog box OK button), commit the tx at the end. The connection though is constantly open (since it's the same session), and thus all opportunities for caching can be used by both Hib and RDBMS.

    It may also be a good idea to implement a transparent session re-open in case the connection went dead -- users tend to leave applications open for extended periods of time, and it should continue to work Monday even if DB server was rebooted on weekend.

    Update

    Jens Schauder provided a reason to use multiple sessions: partial (unwanted) updates to the session. Well, that comes down to the way you use Hibernate.

    Suppose we have two dialogs open (as in Jens' blog example). If user clicks a radiobox, and we immediately update a Hibernate entity associated with this radiobox, then, when user clicks Cancel, we're in trouble -- session is already updated.

    The right way, as I see it, is to update dialog variables (non-Hibernate objects) only. Then, when user clicks OK, we begin a transaction, merge updated objects, commit the transaction. No garbage gets ever saved into session.

    MyHibernateUtils.begin();
    Settings settings = DaoSettings.load();
    // update setttings here
    DaoSettings.save(settings);
    MyHibernateUtils.commit(); 
    

    If we implement such a clean separation of concerns, we can later switch to multiple sessions with a simple change of MyHibernateUtils.begin() implementation.

    As for possible memory leak, well... Transaction.commit() calls Session.flush(), which AFAIK, cleans the cache too. Also, one may manually control the caching policy by calling Session.setCacheMode().

    0 讨论(0)
提交回复
热议问题