-->
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.  [ 30 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Lazy loading with Swing
PostPosted: Thu May 12, 2005 12:43 am 
Regular
Regular

Joined: Wed May 11, 2005 11:57 pm
Posts: 80
I don't see a clean way to make Hibernate work with lazy initialization in Swing. Let's take the following scenario:

* I have a 'Company' entity with a to-many relationship to 'Invoices'
* I have a JTree showing a list of Companies, which can be expanded to show their related invoices
* I'm using a TreeModel that mirrors my data structure, which means that someCompany.getInvoices() will be called to retrieve the list of invoices for the company.

If I create a new Session, fetch a list of Companies, and then close that Session, then I will get a LazyInitializationException when the user expands the JTree. It is important to note that this is not like an HTTP web app, where there is a nice definitive 'begin request' / 'end request' cycle: the user could do many different actions through the UI that could all potentially trigger lazy loads.

Here are some solutions which I've seen posted, none of which I like:

* Keep the session open all the time - the docs repeatedly stress not to do this.
* Modify my TreeModel to open a Hibernate session before calling getInvoices(), close it after reading the list of children - This embeds Hibernate code into my View layer, requires me to write custom data models throughout my app, and is multiplied by the hundreds of cases where I need to retrieve to-many relationships throughout my application. Furthermore, I see dire warnings that I don't understand (apologies for my ignorance) that this will "break the transaction semantics of your application."
* Don't use lazy initialization; do an eager fetch on everything - this won't work for most of my apps, there is a lot of data and performance will suffer.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 12, 2005 2:56 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
Quote:
* Don't use lazy initialization; do an eager fetch on everything - this won't work for most of my apps, there is a lot of data and performance will suffer.


not correct.
Imagine you have 3 heavy views in relation with your root 'Company' entity. Here is a simplified example:
View 1: Company--* A--1 B
View 2: Company--* C
View 3: Company--* C--* D

You just have to write 3 queries which will eager fetch the object graph you need. Remember how HQL is powerfull to do this.
For me, it's not bad to have in your DAO layer methods named getCompanyForView1(),getCompanyForView2(),...
Better, use named queries, you'll only have one DAO method getCompany(String alias).

If you go from view 2 to view 3, you can reattach your entities to retrieve D collection.

Now you can also use DTOs and send DTOs to your heavy views... copying from your entities to your DTOs will fetch what you need.

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 12, 2005 4:31 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
Quote:
* Keep the session open all the time - the docs repeatedly stress not to do this.


AFAIK we just stress to only need if required - and in a swing app this might be required.

/max

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 12, 2005 9:03 am 
Regular
Regular

Joined: Wed May 11, 2005 11:57 pm
Posts: 80
max wrote:
Quote:
* Keep the session open all the time - the docs repeatedly stress not to do this.


AFAIK we just stress to only need if required - and in a swing app this might be required.

/max


Max & Anthony, thanks very much for your quick replies!

Max: I've been leaning in the direction you recommend, of having a long-running session which stays open. However, what happens if there is a HibernateException, for example, we briefly lose a network connection to the DB server? I know I need to close the session in response to the error, would it be valid to open a new session and iterate through every data object I've retrieved, calling reattach with each one so that lazy loads will continue to work?

Anthony: Thanks for your suggestion, I can see how eager loading could be a viable option for some browser-like interfaces. However, my app is not structured with different views, where the user is explicitly switching views and I know when to trigger a re-fetch: instead, I have a single complex view with many trees, lists, and tables that all interconnect through the shared data objects. One JTree in particular in my app is always present on the UI, and it can drill through almost every data object in my relationship graph without ever switching to a different view. Lazy loading would be ideal in this scenario, since I didn't write the TreeModel and thus cannot insert code to trigger Hibernate when a node is expanded (and I wouldn't want to add that to my TreeModel even if I did own the code). Also they might have many different nodes visible, or perhaps only one, so it would not make sense (and the app would run out of memory) if I tried to eagerly retrieve all nested info for every object in the JTree.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 12, 2005 9:06 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
yes.

(but i would still recommend trying to use smaller session scope if possible for better control over consistency)

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 12, 2005 9:18 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
your problem is something like
http://www.canoo.com/ulc/demos/onlineshop.html?

Tree with lazy loading : Explore the product category hierarchy by collapsing and expanding the nodes in the left-hand tree browser using the node handles (plus and minus icons).

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Sat May 14, 2005 10:51 pm 
Regular
Regular

Joined: Wed May 11, 2005 11:57 pm
Posts: 80
anthony wrote:
your problem is something like
http://www.canoo.com/ulc/demos/onlineshop.html?

Tree with lazy loading : Explore the product category hierarchy by collapsing and expanding the nodes in the left-hand tree browser using the node handles (plus and minus icons).


Yes, this is very much like what I'm trying to do. Although it seems as if there is no local caching going on - guessing from the speed, it looks like it is always going back to the server to refresh the list of objects, even when I click back and forth between the same two product categories.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 03, 2005 6:45 pm 
Beginner
Beginner

Joined: Wed May 25, 2005 7:49 pm
Posts: 25
I am fairly new to Hibernate, so please forgive me if my idea is ignorant. I have the same issue: a Swing application with lots of data that I don't want to fetch before sending to the client. I was thinking that I could create a custom SessionImplementor class that would forward any requests to the server and to a Hibernate session (opening if needed). Any thoughts on this idea?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 04, 2005 3:28 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
Baaad idea.

Implement a custom swing treemodel instead that handles this in a safe way instead.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 04, 2005 11:53 pm 
Regular
Regular

Joined: Tue Mar 01, 2005 2:35 pm
Posts: 60
This is a problem as well with component based web apps. But it's made even worse by the fact that eager fetching becomes more expensive the more concurrent users you have.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 04, 2005 11:55 pm 
Regular
Regular

Joined: Tue Mar 01, 2005 2:35 pm
Posts: 60
What is this "reatach" method? If I have an object that may or may not be associated with a dead session, I've yet to find a way to reatach it to a new one without just getting a fresh copy using the primary key. The would be a handy method to know about. :)


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 05, 2005 1:12 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
saveorupdate, lock, refresh etc. are all "reattach" operations meaning they associate the object to the session.

One of them - lock(o, LockMode.NONE) has the ability to do the reattach without doing any save or update.

Read the hibernate book ;)

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 05, 2005 1:23 am 
Regular
Regular

Joined: Tue Mar 01, 2005 2:35 pm
Posts: 60
I have read Hibernate In Action, actually. Cover to cover. Great book. I've tried using Lock, but it throws an exception if the object actually is associated with a session. Actually, now that I think about it, I could just decorate that call in my DAO to catch and drop that exception. If I'm careful and don't use it willy nilly, an exception shouldn't been thrown too often and performance shouldn't suffer... hopefully. :)


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 05, 2005 4:28 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
sounds like a very bad idea

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 05, 2005 11:57 pm 
Beginner
Beginner

Joined: Wed May 25, 2005 7:49 pm
Posts: 25
Max,

I understand what you're saying, but I don't want to have to implement this logic in every place I use those beans. In fact, some of my beans call other beans outside the context of a tree model, so where would I put that logic?

I guess I would just like the logic to be in one place. Maybe Hibernate is not the best solution for this problem? Is there another technology that would better suit my needs?

I really appreciate everyone's help.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 30 posts ]  Go to page 1, 2  Next

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.