dpHibernate - Hibernate lazy loading with Adobe BlazeDS

One of the biggest problems with working with data in a RIA/Flex application is that it's all or nothing. You either need to get all of the data or write a lot of code to return the data in multiple requests. The problem is that good design means that we want to design our data object to match the data, not the UI. For instance a User might have an array of Orders which each have an array of Items. Seems simple enough, right. The problem is that this is a large complex objects which could require a query that joins multiple tables when returning data to your application. No big deal if you want to display all of the data. But if you are just trying to output the users name and email in a search result screen then this is a huge performance hit.

Luckily there is a solution, It is called lazy loading. JSP developers, which use the java hibernate framework, have been able to use lazy loading for years. But until now this did not work with remote client applications like Flex. For those of you who have tried, I'm sure your familiar with the dreaded LazyLoadingException. Frustrating huh. Lazy loading let's your define a complete object model, such as a User with an array of Orders. But only return the data you are actually using in your presentation layer (Flex). Avoiding that all or nothing data problem that is so common.

I'm happy to announce a new Digital Primates open source project. dpHibernate, add support to BlazeDS for Hibernate lazy loading. You can find both the java and the ActionScript parts of the project here: http://code.google.com/p/dphibernate

If you're not familiar with hibernate, check out http://www.hibernate.org. At a real high level, Hibernate is a java ORM tool, which lets you map java beans to a relation database. Hibernate does all of the sql work for you.

So how do dpHibernate work? dpHibernate is actually a combination of two code bases. First, there is a custom java adapter for the BlazeDS server. This HibernateAdapter understands the hibernate proxy objects and knows how to convert them into a special dpHibernate proxy which the AMF serializer will ignore and not try to initialize. This is how the proxy objects are able to go back to the client without getting the LazyLoadingException.

The second part of dpHibernate is an ActionScript library which gives your application the code it needs to understand these dpHibernate proxy objects. This AS library has the code to manage your ActionScript beans and knows how to call back to the server to load a proxy once that object has been touched, usually with a binding expression.

In case your wondering, how does dpHibernate differ from the hibernate support in LiveCycle Data Services ES? For one dpHibernate doesn't require LCDS it works with the open source BlazeDS server. The other big difference is that hibernate support in LCDS requires you to duplicate the lazy associations in the services-config.xml and you need to use an Assembler class to get the hibernate objects. dpHibernate let's you call any java method and return any hibernate object.

So check it out, if you can use it I'd love to hear about it. If it doesn't work for you I want to know about that too. And as with all open source projects this one can use as many eyes as possible on it too. If you find any hibernate configurations that don't work let me know. Or better yet, send me a test case with the right hibernate mapping files to recreate the issue.

Thanks, ---mike nimer mikenimer at yahoo.com

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Steve Brownlee's Gravatar I can't wait to try this. I already know the project in which I'd like to use it.
# Posted By Steve Brownlee | 5/21/08 6:27 PM
Rodrigo P. Fraga's Gravatar Spring Integration?

And is coupled to hibernate, or
I can to use with a JPA implementation?

Thanks!

\o
# Posted By Rodrigo P. Fraga | 5/30/08 9:01 AM
Mike Nimer's Gravatar Yes spring is supported and as for JPA. Right now it's rightly coupled to hibernate class names. However It shouldn't be that hard to do the same thing for jpa in the serializer in the future
# Posted By Mike Nimer | 6/1/08 1:13 AM
Rodrigo P. Fraga's Gravatar Hi!,

I tried to use the dpHibernate, but I didn't have sucess!

My architecture is based in Spring+JPA+Hibernate Entity Manager.

The problem is that, when a lazy object is loaded, it only show the attributes of dpHibernate, such proxy, destination...

The real data, don't load! I think that is the mapping with annotations, because, I use only JPA, I use hibernate as a JPA vendor,
my entities, it don't couple with a framework[Hibernate], only with an API [JPA]

So, do you have any idea?

regards.
# Posted By Rodrigo P. Fraga | 6/1/08 11:33 PM
Mike Nimer's Gravatar Sorry I didn't see this right away, for a faster response can you post any follow ups in the dpHibernate discussion group.

It sounds like you aren't using the HibernateRemoteObject tag in your flex code. So we aren't able to wrap the results and do the right thing to load the proxy when you access a property in flex.

Any chance you post or email me a sample applicationt that I can use to walk through it with the debugger.

thanks,
---mike
# Posted By Mike Nimer | 6/10/08 12:45 PM
Den's Gravatar Mike,

did you check graniteds?

Den
# Posted By Den | 6/11/08 11:21 AM
Mike Nimer's Gravatar Yes I did, the difference is that this is a new adapter that works inside of official Adobe servers (BlazeDS and LCDS). Grantie also has hibernate lazy loading support too, but it is a whole new server. Plus I don't like the way it requires you to write your own externalizable methods. The idea with dpHibernate is to make it as seemless as possible to plug in.
# Posted By Mike Nimer | 6/14/08 1:58 PM
Bath pillows's Gravatar I tried to use it, but it has a lot of bugs.
# Posted By Bath pillows | 6/22/08 9:23 AM
Ray M.'s Gravatar At a real high level, Hibernate is a java ORM tool, which lets you map java beans to a relation database. Hibernate does all of the sql work for you.

http://www.ipodaccessories.net
# Posted By Ray M. | 7/26/08 7:06 PM
Tadeu Rodrigo's Gravatar dpHibernate it´s really great!! I´ve just follow the setup/configuration
and everthing works fine. I´m using them with many tables
and relationships (one-to-many, many-to-one, many-to-many) working with lazy.
Besides, I had a problem with lazy at hibernate. I changed at hibernate configuration
files (cfg.xml) the propertie fetch="join" that solve the problem. But, there´s only one
error:
java.lang.NoSuchMethodError: org.hibernate.Query.setResultTransformer(Lorg/hibernate/transform/ResultTransformer;)Lorg/hibernate/Query;

at net.digitalprimates.persistence.translators.hibernate.HibernateSerializer.getPkIds(HibernateSerializer.java:426)
at net.digitalprimates.persistence.translators.hibernate.HibernateSerializer.getCollectionProxies(HibernateSerializer.java:365)
....

Any idea to solve this problem? The application works fine, but I want to solve this ;-)

[]´s
# Posted By Tadeu Rodrigo | 10/8/08 12:48 PM
Tadeu Rodrigo's Gravatar dpHibernate it´s really great!! I´ve just follow the setup/configuration
and everthing works fine. I´m using them with many tables
and relationships (one-to-many, many-to-one, many-to-many) working with lazy.
Besides, I had a problem with lazy at hibernate. I changed at hibernate configuration
files (cfg.xml) the propertie fetch="join" that solve the problem. But, there´s only one
error:
java.lang.NoSuchMethodError: org.hibernate.Query.setResultTransformer(Lorg/hibernate/transform/ResultTransformer;)Lorg/hibernate/Query;

at net.digitalprimates.persistence.translators.hibernate.HibernateSerializer.getPkIds(HibernateSerializer.java:426)
at net.digitalprimates.persistence.translators.hibernate.HibernateSerializer.getCollectionProxies(HibernateSerializer.java:365)
....

Any idea to solve this problem? The application works fine, but I want to solve this ;-)

[]´s
# Posted By Tadeu Rodrigo | 10/8/08 2:02 PM
BlogCFC was created by Raymond Camden. This blog is running version 5.9.001.