-->
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.  [ 6 posts ] 
Author Message
 Post subject: Sharing hibernate entities between threads
PostPosted: Wed Aug 29, 2007 6:07 am 
Beginner
Beginner

Joined: Tue Aug 21, 2007 4:58 am
Posts: 30
Hello,
I have the following problem.
I have a service which at a point determines if a query must be run background or not. If it determines that it must be done in background it runs a thread.Executes the query and returns the result.
The problem rises when I try to access objects through lzy fetch. The session it´s open at the thread and closed when the thread finishes.
The two solutions I come up are, passing the session to the thread or reattaching the result to the session. It is imposible to make the relationshops with fetch type eager.
Does anyone have another idea??
Regards


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 29, 2007 1:43 pm 
Red Hat Associate
Red Hat Associate

Joined: Mon Aug 16, 2004 11:14 am
Posts: 253
Location: Raleigh, NC
You cannot ever share Session between threads. Either break up the work into smaller pieces (avoiding lazy-loaded associations completely) or block on the query instead of forking it off. I can't imagine a scenario where eager fetching is impossible. It sounds like you've got too many associations and you need to split your model up a bit.

My $.02.

-Chris

_________________
Chris Bredesen
Senior Software Maintenance Engineer, JBoss


Top
 Profile  
 
 Post subject: Re: Sharing hibernate entities between threads
PostPosted: Wed Aug 29, 2007 3:11 pm 
Beginner
Beginner

Joined: Mon Aug 27, 2007 8:10 am
Posts: 37
Bradox wrote:
Hello,
I have the following problem.
I have a service which at a point determines if a query must be run background or not. If it determines that it must be done in background it runs a thread.Executes the query and returns the result.
The problem rises when I try to access objects through lzy fetch. The session it´s open at the thread and closed when the thread finishes.
The two solutions I come up are, passing the session to the thread or reattaching the result to the session. It is imposible to make the relationshops with fetch type eager.
Does anyone have another idea??
Regards


Just an idea - spawn a thread on the client, open a new session with the backend in that thread and use this session to run your query and get results back to the client.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 30, 2007 2:58 am 
Beginner
Beginner

Joined: Tue Aug 21, 2007 4:58 am
Posts: 30
Quote:
eager fetching is impossible

The thing it´s that I´m working on a very big project that manages the statistics of my country among other things. Therefore some querys retreive millions of objects and sometimes I do not need to access all the info, so it is very expensive to load all the relations when I might not need that info. That it´s why I do not want to make eager fetching.
Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 30, 2007 5:58 pm 
Beginner
Beginner

Joined: Tue Oct 10, 2006 3:23 am
Posts: 33
Bradox wrote:
Quote:
eager fetching is impossible


You should then reattach the object graph (to a new session) when you object is ready to be viewed. I even wrote some code a while ago that looks at an object , see if it has null property and reattaches if so, something like:
Code:
protected Object relinkEntity(Object entity) {
      ...
      Class clazz = entity.getClass();
      Field fields[] = clazz.getDeclaredFields();
      
      if (log.isTraceEnabled())log.trace(Arrays.toString(fields));
      boolean mustFetch = false;
      for (Field f : fields) {

         ...

            if (mappedClasses.contains(f.getType())) {

            // We have a mapped entity, lets check it.

            Object fieldValue = null;
            try {
               fieldValue = PropertyUtils.getSimpleProperty(entity, f.getName());
            } catch (Exception e) {
               log.debug("could not get value for field:" + f);
            }
            if (fieldValue != null) {
            
               Object newEntity = relinkEntity(fieldValue);
               // We don't have the same one, it has been replaced by a
               // hibernate proxy.
               if (newEntity != fieldValue) {
                  try {
                     PropertyUtils.setSimpleProperty(entity, f.getName(), newEntity);
                  } catch (Exception e) {
                     log.debug("could not set field:" + f + " to value" + newEntity);
...
         
      if (mustFetch) {

         Serializable key = HibernateUtils.getIdentifierValue(entity.getClass(), entity);
         
         if (key != null) {
            
            Object newEntity = loadEntity(entity, key);
            return newEntity;
         }else{
            log.debug("key was null for:"+entity);
         }
         
   ...


* rate if this helps *[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 31, 2007 3:18 am 
Beginner
Beginner

Joined: Tue Aug 21, 2007 4:58 am
Posts: 30
Thanks a lot, the code looks very interesting, but at the end what I did was to set the cascade to lock and it works without reattaching. At the end the problem wasn´t the session but that there were to many relations and some of them weren´t attached to the session.
Thanks.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 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.