views:

557

answers:

4

It has been suggested that in order to improve performance of our system that the use of lazy loading should be used across the board. That is to change the OneToOne mapping with the “mappedBy” property to the @OneToMany mapping. This is to address and stop the loading of unwanted data from the database which leads to slowness of the applications.

We run a multi-tier system (basically 2 tier). We have the front end - using JSF and the back end which contains the business and database access layers. Front and back communicate view EJB - but EJB have no real logic in them. Other technology used - Spring and Hibernate

Now, after some reading on the topic it seems that the usage of lazing loading is not a silver bullet in that it needs to be applied correctly. For each lazy loading, a Select statement will be issued to fetch the data. There is also the issue that if the front end makes access to a property that is to be lazy loaded and the session/connection is closed on the back end, then we will get a null.

Is the above a correct concern?

So, what is the best approach/practice to go about in implementing a lazy loading solution or performance improvement? The hope is not to redo the data model if at all possible.

My initial though was to work with the DBA group to get an ideal of what is going on between the two systems - how the queries look, how we are using the data etc. Identify trouble spots, examine the Hibernate object/queries to see how best to improve it. Also to look at the front end to determine what and how the data is passed from the back to the front to be displayed etc.

Good approach/other approaches?

A: 

Lazy loading is great for delaying expensive operations, but I agree with your conclusion that it's not a silver bullet to solve all performance issues.

Go with your gut instinct and do some analysis first to see where the real performance problems are in the application. It may turn out that lazy loading some data will be a good solution, or it could be something completely different. There's really no way to tell until you start profiling and analyzing what is going on inside the app.

Eric Petroelje
+5  A: 

The very first thing you should do is measure your application and find out what exactly is causing your performance issues.

Use a tool like JProfiler to find out where the issues are.

Once you know what's going on you can then decide how you're going to fix it.

Just going straight to implementing a lazy loading scheme without knowing what's causing your performance issues will be a waste of your time.

If you discover that the DB layer is where your issue is then you can get the DBA's involved to see if your schema / queries can be improved before doing anything more radical.

Glen
I am normally wrong where I think the slowdowns are, so I have learned to profile rather than guessing.
James Black
@James, yeah, I've been bitten too many times by trying to guess what the bottleneck is. It's just easier, faster and more accurate to measure the code somehow before making any changes.
Glen
A: 

It so much depends on what you are trying to do, that it is difficult to say. Your idea of going to your DBA could be productive, definitively. The only thing people might be able to do is provide some examples. In my case:

Lazy loading was a huge performance improvement for us in the following scenario. We had a huge tree with 15,000 nodes with different levels. Originally we tried to load the whole tree and then render it. It took ages. We changed the code to load the branches lazily only when the user expanded the nodes. It takes slightly longer on node expansion, but the application overall feels faster. In this case it makes sense to change the mapping

Now, if you need to process the whole tree anyways, because it is required by your business logic, lazy loading is not going to be much of a difference. In this case just changing the mapping is really no solution, and it might even be more expensive.

You need to think a little bit on what your application does, on where does it feel slow, on what are you trying to accomplish. Pulling out a profiler is also no silver bullet.

Without specific examples from your application it makes no sense to say if lazy loading is useful or not.

Mario Ortegón
A: 

It is true that if your fetching of data is slowing your load times down, then lazy loading is a great solution. But applying it across the board seems to be a premature optimization. You would probably want to impliment it for each set of data and then test to see if it speeds up the app. If it does not, then it is not a good candidate for the lazy loading.

The way I have implemented the lazy loading caused no change in the data tier. It was all down in the business logic and presentation controllers. As I am not familiar with EJB I am going to assume that this will work for your java app. Any way, When I implement the lazy loading, I load no data (atleat none of the data I am going to load lazily), until it is needed. Then I call the data tier and get my data (or a subset of the data).

As for the connection concern, you will need to put checks in place to test the data connection to see if it is closed. That is, is you are pooling the data connections. Then if the connection is closed, then reopen it. But as with the actual lazy loading implementation, this should be done in your logic classes and not in the front end, so you don't have to duplicate this functionality many times.

aquillin