-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 
Author Message
 Post subject: Swing app w/ HibernateUtil ThreadLocal - many threads?
PostPosted: Fri Jul 07, 2006 9:21 am 
Newbie

Joined: Fri Jul 01, 2005 4:36 pm
Posts: 11
Location: US
I am using Hibernate 3.2 cr1 in a Swing app in a non-managed environment. I connect directly to my database - there is no EJB, J2EE, etc..

I am using the ubiquitous HibernateUtil code and am a bit confused about the ThreadLocal usage where the session is bound to the thread.

I want to use SwingWorker to spin off some new threads and make my UI more responsive - for example, retrieving data in a particular thread while using another thread for the UI or whatever. The same thing could happen when I persist transient instances back to the database. Heavy DB work should not happen in the EDT (Event Dispatch Thread).

This means that the thread and session that I use to get transient instances could be different than the thread and session I try to use to persist changes in those transient instances. As I understand it, this won't work in Hibernate.

My questions:
-If using ThreadLocal, is my only option to go with detached instances, so that persisting in a different session and thread will work, or am I misunderstanding the usage of ThreadLocal in HibernateUtil?

-Does it make sense to use detached instances in a non-managed Swing app environment?

-Does HibernateUtil, with ThreadLocal, preclude the use of multithreaded interface code?

Any advice greatly appreciated.

allen


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 07, 2006 9:41 am 
Regular
Regular

Joined: Wed Sep 28, 2005 6:45 pm
Posts: 56
I think you should use the simplest HibernateUtil if you are running in an unmanaged environment, but, I am a newbie, so I might be wrong.

In other words:
Code:
package util;

import org.hibernate.*;
import org.hibernate.cfg.*;

public class HibernateUtil {

    private static final SessionFactory sessionFactory;

    static {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            sessionFactory = new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

}


Look at the info in http://www.hibernate.org/hib_docs/v3/re ... tions.html

11.2.1. Non-managed environment


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 07, 2006 9:54 am 
Expert
Expert

Joined: Tue Dec 28, 2004 7:02 am
Posts: 573
Location: Toulouse, France
In fact, there's no more need to use ThreadLocal object in HibernateUtil. It can be done automatically defining the property
Code:
<property name="current_session_context_class">thread</property>
in hibernate.cfg.xml

http://www.hibernate.org/hib_docs/v3/re ... pp-helpers

I'd say yes. You will have to work with detached instances and reattach them when you want to persist changes. Why don't you try to synchronize the hibernate code so you're sure you won't encounter concurrency problems ? Every threads would access the same threadsafe single object that will perform the db operations ?

_________________
Baptiste
PS : please don't forget to give credits below if you found this answer useful :)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 07, 2006 11:58 am 
Newbie

Joined: Fri Jul 01, 2005 4:36 pm
Posts: 11
Location: US
batmat wrote:
In fact, there's no more need to use ThreadLocal object in HibernateUtil. It can be done automatically defining the property
Code:
<property name="current_session_context_class">thread</property>
in hibernate.cfg.xml

http://www.hibernate.org/hib_docs/v3/re ... pp-helpers

I'd say yes. You will have to work with detached instances and reattach them when you want to persist changes. Why don't you try to synchronize the hibernate code so you're sure you won't encounter concurrency problems ? Every threads would access the same threadsafe single object that will perform the db operations ?


Oh - okay. I'm familar w/ current_session_context_class = thread, but I though this was used to indicate to Hbn that I was using ThreadLocal in my code rather than it being a *replacement* for ThreadLocal. Looking at org.hibernate.context.ThreadLocalSessionContext, this makes sense now.

Your synchronization suggestion is great, but isn't that only half the issue?
Its not that I have 2 threads using the same session - I have 2 threads using 2 different sessions. If I want to get a persistent object in one session/thread, and then save updates to it in the other session/thread, what do I do? It looks like I can bind() my thread to a particular session, but how do I abstract this away in my DAO layer? Detached instances? ugh


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 07, 2006 12:07 pm 
Expert
Expert

Joined: Tue Dec 28, 2004 7:02 am
Posts: 573
Location: Toulouse, France
Well yes, I'd say. Use detached instances in the upper layers than your service/dao ones. Then when you want to update it, reattach them with a lock(yourObject,LockMode.UPGRADE);

_________________
Baptiste
PS : please don't forget to give credits below if you found this answer useful :)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 07, 2006 1:11 pm 
Newbie

Joined: Fri Jul 01, 2005 4:36 pm
Posts: 11
Location: US
batmat wrote:
Well yes, I'd say. Use detached instances in the upper layers than your service/dao ones. Then when you want to update it, reattach them with a lock(yourObject,LockMode.UPGRADE);


hhmmmmm....ok

But why would I use lock(yourObject,LockMode.UPGRADE) rather than update(yourObject)??


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 07, 2006 2:48 pm 
Expert
Expert

Joined: Tue Dec 28, 2004 7:02 am
Posts: 573
Location: Toulouse, France
Well, you seem to be right : for an update, it seems the lock() is not to be done :
Quote:
After reconnection, to force a version check on data you aren't updating, you may call Session.lock() with LockMode.READ on any objects that might have been updated by another transaction. You don't need to lock any data that you are updating.


So update() should in fact be ok for you.

In fact, lock() has to do with the versionning system :
http://www.hibernate.org/hib_docs/v3/re ... e-detached

In your highly-concurrential environment, maybe you should consider using version property.

If you can detect modifs of your beans, in the case you're sure it has not been touched, there's also this interesting statement in the ref doc :
Quote:
You may also call lock() instead of update() and use LockMode.READ (performing a version check, bypassing all caches) if you are sure that the object has not been modified.

_________________
Baptiste
PS : please don't forget to give credits below if you found this answer useful :)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 02, 2006 3:55 am 
Newbie

Joined: Tue Sep 12, 2006 3:19 am
Posts: 6
Hi Allen,

How did it eventually go ?
Anymore tips on Swing + Hibernate ?
How did you manage transactions/swingworker ?

Geert


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.