Using DWR with Spring and Hibernate
For the past few weeks, I've been developing an application using Struts, Spring, Hibernate and the DWR project for my XmlHttpRequest framework. As you might remember, I used JSON-RPC for Ajax stuff on my last project. I found DWR to be much more full-featured and easier to use. This post is meant to capture some issues I encountered so others won't have to jump the hurdles that I did. For those of you that get bored quickly, here's a movie (QuickTime) of the app's Ajax features.
I've been using version 0.4 of DWR, and I haven't had a chance to try out version 0.5. When I first started using it, I ran into a ThreadDeath problem that was easily resolved by changing a log.debug message to System.out.println. I tried to reproduce this issue yesterday and couldn't, so who knows what that was all about. As far as configuring DWR in your webapp, that's pretty easy to do, and well documented. See the project's documentation or this Spring MVC HowTo.
Here are a few things I remember from my development experience.
- The examples are great, especially how to dynamically edit a table.
- When developing, make sure to set the "debug" init-param to "true". This allows you to go to http://location:8080/yourapp/dwr and see a screen that allows you to call methods on your exposed classes.
- In WEB-INF/dwr.xml, you need to specify a converter for each POJO you want to expose to your UI via JavaScript. I started out by converting a whole package, but found this to be *extremely* slow (we have a package of around 50 DTOs). So I changed it to be only the DTOs I was using. This turned out to take about 30 seconds to do the conversion, and was again unacceptable. The problem turned out to be that the converter was invoking all the lazy-loaded children for each DTO. My final solution was to create a NameValue object and only convert that. Then in my Spring bean, I populate it from DAOs and DTOs. I'm using Spring's OSIVF for Hibernate to ensure that DWR doesn't invoke lazy-loading.
- I had to override a few of DWR's JavaScript functions in util.js b/c they didn't work for me. I changed showById() and toggleDisplay() to use style.display='' instead of style.display='block' b/c this is what I've always used and block doesn't work that well. I also changed useLoadingMessage() to have a cleaner-looking load message.
- I used the Fade Anything Technique in this project and found that IE likes to have full 6-digit hex values for colors in CSS rules. The shorter 3-digit hex values simply don't work in IE.
- Using "test" buttons that only showed up for my username proved to be a great way to test the UI and the Ajax stuff. These buttons called a number of JavaScript functions to drive the UI and wait between invoking different functions using window.setTimeout.
All in all, using DWR was a great experience and I definitely plan to use it more in my projects. The client loves the app - especially since it's wicked fast and seems to work like a desktop app.
Posted by Lars Fischer on April 28, 2005 at 09:24 PM MDT #
Posted by 217.185.82.43 on April 28, 2005 at 09:27 PM MDT #
Posted by Jon Harper on April 28, 2005 at 10:04 PM MDT #
Posted by Matt Raible on April 28, 2005 at 10:18 PM MDT #
Posted by Adam Michela on April 29, 2005 at 02:06 AM MDT #
Posted by Matt Raible on April 29, 2005 at 02:54 AM MDT #
Posted by My Own Little World on April 29, 2005 at 03:09 AM MDT #
Posted by Ajaxian Blog on April 29, 2005 at 06:27 AM MDT #
Do I need a special codec?
Quicktime simply says that a "required compressor" is missing.
VLC's error log: "no suitable decoder module for fourcc `rle '."
Thanks.
Posted by foo on April 29, 2005 at 08:09 AM MDT #
Posted by Lars Fischer on April 29, 2005 at 08:22 AM MDT #
Posted by Matt Raible on April 29, 2005 at 01:32 PM MDT #
Posted by John Christopher on April 29, 2005 at 05:56 PM MDT #
Posted by Sanjiv Jivan on May 01, 2005 at 01:14 PM MDT #
Got it to work.
[foo said:Do I need a special codec?]
I had Internet Explorer disabled, when I re-enabled it, quicktime made a call for a codec through IE. I had the minimal install of Quicktime, so it would seem the codec is not present in the minimal setup. Not sure why Quicktime was unable to find Firefox.
[Matt Raible said:I tried it on my Windows XP SP2 box with both IE and Firefox]
I only tried to play it from local disk - never used the plugins. So, unsure if using the browser plugins would have made a difference.
Nice work on the app!
cheers
Posted by foo on May 01, 2005 at 06:03 PM MDT #
Posted by Stephan Schwab on May 01, 2005 at 09:53 PM MDT #
Posted by Dan Novik on May 02, 2005 at 12:50 PM MDT #
Posted by Paul on May 04, 2005 at 01:33 AM MDT #
Posted by John Fereira on May 04, 2005 at 12:44 PM MDT #
John - this app is something I developed internally for a client. It will not be made available publicly.
Posted by Matt Raible on May 04, 2005 at 04:47 PM MDT #
Posted by Paul on May 05, 2005 at 05:24 PM MDT #
Posted by Cristiane on June 23, 2005 at 05:13 PM MDT #
Posted by Matt Raible on July 12, 2005 at 05:00 AM MDT #
Posted by Bill Schneider on August 04, 2005 at 02:46 AM MDT #
Posted by peter on May 08, 2006 at 02:03 AM MDT #
Posted by Matt Raible on May 08, 2006 at 03:53 AM MDT #
Posted by Eric Viegas on May 10, 2006 at 05:29 PM MDT #
Posted by Misha Gavryuchkov on July 13, 2006 at 10:06 PM MDT #
Posted by Deepak Kumar on November 19, 2006 at 04:22 PM MST #
Posted by k jagdishchandra on March 24, 2007 at 09:39 AM MDT #
Posted by Deha Peker on June 09, 2007 at 04:54 AM MDT #
regarding this: "The problem turned out to be that the converter was invoking all the lazy-loaded children for each DTO. My final solution was to create a NameValue object and only convert that."
I think a better solution, almost for lazy progammers like me, is excluding lazy-loaded children properties:
Posted by tonig on February 09, 2008 at 03:11 PM MST #