Platinum Partner
java,sql,frameworks,hibernate,persistence,jboss mq,lazy loading,proxy,serialisation

JBoss MQ and Hibernate Lazy Loading

Today I will present a recent problem which I have faced in enterprise applications with an architecture that is based on DMZ and communications between backend and frontend using JBoss messaging.

In the integration step, I used the Hudson integration tool to get binaries. For this utility, I get one war file to be deployed in JBoss 4.2.3 GA and a second jar. The backend ( second jar ) communicates with the database using the Hibernate persistence provider and shares two JMS queues with the frontend. These binaries worked correctly on a developer machine but it's not the case in my laptop.

Investigations :

With no explicit exceptions, I start by debugging the frontend. To debug JBoss start it in debug mode:

export JAVA_OPTS="${JAVA_OPTS} -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,adress=8888"

Next start JBoss and attach a debug socket using Netbeans facilities. With suspend=y, we can debug the init servlet method. if there are no errors there, set the flag to suspend=n. After some steps, I fixed the source of my problem

Problem

The backend requests the databse using Hibernate with lazy loading mode for collections. When the entity is serialized to be sent in the JMS queue, the frontend will try the get message from queue and cast it to appropriate entity class as sent by the backend. But this cast has failed. Why?

In fact, the backend comes with it's own version of Hibernate and my JBoss server has it's embedded Hibernate jars. Lazy loading in Hibernate collections means creation of proxy collection object to be filled if we try to get it inside a session, otherwise we get an exception.

The problem is due to static final long serialVersionUID  which is different in two proxy collections. The frontend can't read that entity because it doesn't have the same class identity as sent by the backend.

Solution

As a first solution, I used the same Hibernate lib for the backend and it worked fine. But serious attention should be taken to avoid sending proxy through a network if we can't be granted to have the same libraries. if I had used another JEE server, such as Glassfish, I don't encounter these problems as I use EclipseLink by default and I will deploy the same backend library.

Otherwise should we use value objects with entities to avoid theses problems?
{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks
Tweet

{{parent.nComments}}