-->
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: Why does the LazyLoadingException exist?
PostPosted: Tue Jul 22, 2008 6:59 pm 
Newbie

Joined: Tue Jul 22, 2008 6:43 pm
Posts: 3
Perhaps it's an ignorant question but I've been using Hibernate (in an RCP application) for a couple of months now and it suddenly occured to me that this seemed odd.

It seems like, instead of throwing an exception, Hibernate could start a transaction, load the data you asked for, and close the transaction. Is it missing some critical piece of information that it would need in order to do that?

As I write this I'm wondering if the problem has something to do with the session, maybe Hibernate doesn't know anything about the session at this point?

Anyway, if it were possible for Hibernate to load the data rather than throw an exception it would make using Hibernate in RCP apps much easier. Constantly opening and closing transactions to avoid LazyLoadingExceptions is a bit...tedious.

If anyone knows why this can't be done I'd appreciate hearing it.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 23, 2008 4:50 am 
Newbie

Joined: Sat Jul 12, 2008 4:25 am
Posts: 8
Hi,

Imagine what might happen if Hibernate would open and close a transaction just for initializing a lazily loaded entity without you knowing it:

Before the transaction was closed, your object graph was in a consistent state. What you now suggest is that Hibernate should implicitly reattach your object graph, initialize the lazily loaded references and close the transaction. I think automatically reattaching objects is not really a good idea, because you may end up having your whole db in memory. And what happens if reattaching is not possible, because an detached object was deleted in another transaction. Hibernate has to throw an exception then.

I think it's not a good idea to give up controlling your transaction and that's the reason why Hibernate throws LazyLoadingException.

Regards,
Matt
[/list]


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 23, 2008 10:39 am 
Newbie

Joined: Tue Jul 22, 2008 6:43 pm
Posts: 3
Thanks for the reply. Grats on the point.

You may be right that it isn't a good idea, it would explain why it isn't implemented this way.

However, I don't see how the problems you suggested could happen.

Anytime I've found a point in my code where a LazyLoadingException occurs I add the necessary code to open a transaction, load(reattach) the necessary object, and finally get the data I want. I always want the data I'm asking for otherwise I wouldn't ask for it. Doing this never causes the entire database to be loaded.

You are right that there could be situations when it should throw some other type of exception, but the exception would be because of something that Hibernate can't handle. What I'm suggesting is something that Hibernate could (possibly) handle.

The LazyLoadingException seems like Hibernate is saying, "I know what you want and I know how to do it but I'm not going to."


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 23, 2008 12:09 pm 
Expert
Expert

Joined: Thu Jul 05, 2007 9:38 am
Posts: 287
While the answer above is the standard answer given to the question, I do not agree (just as you do).

1. It is a mistake to assume that your session is in a consistent state, in the meaning of 'all selected data reflects its status at the beginning of the transaction'.
a) This kind of read consistency is normally not guaranteed by a database. Instead you get the data in the status of the time of the select, which might vary for data coming from different tables/selects
b) if configured to that effect, hibernate will release jdbc connections after a select as long as no dml is issued. That will break the 'consistent' status for sure

2. Ending up with the whole database in memory is a potential problem, but has nothing to do with the problem at hand. If one hits such an exception, the developer won't go "Oh no, I can't have that object, my session is closed, I guess I have to use random data". No she will either keep the original session open or open a new one to manually load the required data. The Complete Database in Session Problem is one of partioning your object graph and evicting objects from your first level cache aka session. Normaly by closing the session.

As I see it the whole problem is one of perspective:
Hibernate is largely used in web applications. There the session handling is easy, and Exceptions as the one discussed occur when your Object was attached to a session from a previouse request. Your sure don't want to revive that session. So throwing an exception is a good thing.

In a rich client (two tier) scenario this is way different. The way sessions are handled/implemented is a serious problem, although solutions exist non will make you really happy. Automatic reattaching would be a great help and really not that much of a problem (at least no one showed me one).

Jens

_________________
Please rate useful posts.


Schauderhaft: Softwaredevelopment, Projectmanagement, Qualitymanagement and all things "schauderhaft"


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 23, 2008 4:38 pm 
Newbie

Joined: Sat Jul 12, 2008 4:25 am
Posts: 8
What's the difference between a 2-tier and a 3-tier application with regard to hibernate? A 2-tier application can possibly hold more state than a 3-tier application with a web presentation layer, because a web session resides on the server and server resources are limited to the servers available memory size. (BTW: 3-tier appliaction that are not web based can also hold as much state as a 2-tier application;-) So it's a wise design decision to restrict the amount of state in the session of a web application. And in a web application each user action is normally executed in the context of a transaction that is controlled by the web application. The same should be true for a 2-tier application, why should the hibernate session behave different in this scenario?Why does it make more sense to automatically reattach deattached entities in a 2-tier application? I still didn't get your point!

A curious
Matt


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 23, 2008 7:12 pm 
Newbie

Joined: Tue Jul 22, 2008 6:43 pm
Posts: 3
I don't know what the difference is between using Hibernate in a client-server application versus a web application because I haven't used Hibernate for a web application.

My main point is from the "anti-redundancy" perspective. Whenever I repeat the exact same code over and over I start asking "why".

For example, let's say I have an Employer object I've pulled from the DB and then closed the transaction. The employer has a set of employees and sets of other things.

-I've used that data to populate a TreeViewer with the Employer as the root node.
-All the nodes below the root contain data that is in a 'lazy' state because it would be ineficient to load large amounts of data that the user may not even look at.
-Now the user clicks the tree to expand the node that contains all of the Employees that work for that employer. You get a LazyLoadingException.

My question is why? I obviously want the employees, Hibernate knows what I want, Hibernate knows (I think) how to get the data. Why not simply load the data rather than making me add code for the sole purpose of preventing an exception that is always solved in exactly the same way?

I can't think of a case where I'd get a LazyLoadingException and not add the code to prevent it.

So if adding the same code is always done every time there is a LazyLoadingException, why not change Hibernate to do what the code you're adding does?

Obviously, in my scenario above there are issues to be handled, such as the Employer being deleted from the DB between the time I loaded it and the time the user clicked the tree. Exceptions would be used or created to handle that kind of thing but those exceptions would make sense because they would be for things that Hibernate clearly can't handle by itself.

And that's the real question, is there some reason Hibernate can't handle LazyLoadingExceptions itself?

If there is a reason, I think it has to do with Hibernate not having a known session at the time and maybe it's considered "bad" for Hibernate to create its own sessions. Theoretically, you could end up with a lot of sessions being created. That's a reason I could buy; although I'd still argue for the option to make Hibernate auto-handle LLExceptions.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 25, 2008 3:49 am 
Expert
Expert

Joined: Tue May 13, 2008 3:42 pm
Posts: 919
Location: Toronto & Ajax Ontario www.hibernatemadeeasy.com
Anti-redundancy is certainly a admirable goal, but we don't want our apps to be smarter than us. It's a real dangerous zone when the applications do too much and the developers lose control. I always hear that complaint about frameworks, that they hide too much. I think Hibernate has really struck a good balance.

_________________
Cameron McKenzie - Author of "Hibernate Made Easy" and "What is WebSphere?"
http://www.TheBookOnHibernate.com Check out my 'easy to follow' Hibernate & JPA Tutorials


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 28, 2008 5:37 am 
Expert
Expert

Joined: Thu Jul 05, 2007 9:38 am
Posts: 287
In reply to katmatt:

The difference for a 2-tier Application and a 3-tier Application is the definition of a unit of work, which in turn defines the scope of your session.

In a 3-tier application a roundtrip is a natural candidate for a unit of work. And most web application probably use exactly that.

In a typical 2-tier application (swing or similiar) one gets a lot of things that don't tie to a unit of work in a obvious way.

One example is displaying a search result in a list.

In 3-tiers/web if you want to go to the next page of results, you hit a link or button, thus performing a new request to the app-server, which in turn starts a new hibernate session / unit of work. Even if you want to reuse a longrunning session, there is a obvious place for it: the http-session

In 2-tiers a thing like scrolling, or hovering you mouse over a cell might trigger lazy loading; You spawn editors from the search result; You drag stuff from one window to another. Where is the unit of work in these cases? It is not so easy as in webapplications. And it is not natural.

This realy comes from the 'old days' of JDBC: In a Rich Client Application you typically have one or a small number of connections, open and used for the whole lifetime of the client. Owned by the lifetime of the client.

In Webapplications one of the first things everyone realizes is: You have to start with a clean connection (from the pool) with every request.

Of course you could code your 2-tier application just as a 3-tier application. But in many cases this is a lot of work with negativ impact on usability and no benefit (apart from knowing how to handle your hibernate sessions)

Jens

_________________
Please rate useful posts.


Schauderhaft: Softwaredevelopment, Projectmanagement, Qualitymanagement and all things "schauderhaft"


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.