Flex Pasta » 2010 » April
The problem is common when using BlazeDS and Hibernate: Lazy loading is not possible without inflating a large object graph. The most common solution to the problem is to “break” parts of the model into manageable pieces based on how the application works. So while there should be a many to many relationship between two entities, maybe it is just left off to avoid problems. This can fragment the object model. When the object model becomes fragmented, it causes extra code to be written to make up for the lack of a correct object model.
A different approach to the problem
Another approach to keep the model pure but avoid large data loads is to use a serialization profile. This means keeping the model the the way it should be, but defining profiles on service methods to determine what parts of the graph are inflated during serialization. Most of the time a service provides functionality to one part of an application, or multiple parts that are used in a similar manner. It is more common for an object model to be used differently in different places of an application. Therefore it makes sense to single out service calls to determine object inflation.
How BlazeDS comes into it
A while back I wrote a post regarding annotations for remote objects with BlazeDS. I have expanded the annotated bean proxy to include this concept of a serialization profile. I also created a small demo project to show just how easy serialization profiles could be used.
My ‘Pet’ Project
Take a look at the following image showing the model for the pet project. As you can see, the pet class has 4 one to many relationships.
Now take a basic flex application that has a datagrid with a list of pets. Clicking on a pet results in the details being shown.
This query in hibernate is something like this: getHibernateTemplate().loadAll(Pet.class); The result would be one query for the list of pets plus and then n+ queries for all of the collections as serialization happens. In this case the whole database of records would be loaded. For 3 record this is ok, but for a large number of pets we could be waiting a long time as the entire database is loaded simply because we cannot have lazy collections.
How to use a Serialization Profile
Now let’s show how a serialization profile would help. Here is the small snipet of code for my service method:
@SerializationProfile(profile = “petList”)
public List<Pet> getAllPets()
{
return petDao.getAllPets();
}
@SerializationProfile(profile = “petDetails”)
public Pet getPetById(Integer id)
{
return petDao.getPetById(id);
}
I have used the new annotation tag @SerializationProfile to define the profile for the remote methods. The second step is to set profiles on lazy loaded one to many collections in my Pet class.
@FlexField(profiles = “petDetails”)
@OneToMany(fetch = FetchType.LAZY, mappedBy = “pet”)
public List<VetVisit> getVetVisits()
{
return vetVisits;
}
I can place one to many profiles on each getter method to determine its serialization profile. I only placed one getter example here, but all 4 of my collections on Pet.class have been set the same way. The all have a profile of petDetails. This tells the proxy, hey, I only want to load these collections when the profile method is petDetails. Our method call to getAllPets() now results in one query ran and only a list of pets returned, without all the extras. Once a user clicks on a pet, the getPetById() method is called. This method has a profile of petDetails, so all the collections are inflated upon return to flex.
Summary
By using the new Serialization Profile annotation and bean proxy, we were able to keep our model pure without inflating everything. I was able to inflate the Pet object when demanded by the application and avoid it when not needed. When other parts of the Pet application are written, they can utilize the full power of the object model without fear of various collections inflating themselves. The performance effect(of a serialization profile) is very minimal and the performance hit(while minor) is only the first time an object is serialized.
Do you think this would be helpful on a project?


