One of the smartest moves in J2EE (or JEE, who cares…) is how Hibernate has influenced the Persistence API. You can smell the Hibernate flavor. This API is a light wrap of Hibernate. If you are familiar with Hibernate, POJOs and hbm.xml files, you can start working with EJB3 Entities.
One of the magical things of Hibernate is how to retrieve graphs of objects ‘lazily’. You can do things like:
and Hibernate takes care of retrieving information from the tables PROVINCE, COUNTRY and LANGUAGE to populate the mapped POJOs. The magic wand is what they call ‘Instrumentation’ of the POJOs: They manipulate the bytecode in runtime thanks to the cglib library.
This approach has a lot of advantages, but a little disadvantage. If you want to transfer an instrumented POJO from one application to another application using RMI (or CORBA), you will need all the Hibernate libraries in both sides. Why? Because the instrumented POJO references Hibernate classes. This process is done transparently to the developer (and this is great!), but it arises as something annoying when using remote invocations. A couple of years ago, I tried to use Hibernate POJOs inside SLSB EJBs, and instead of using Transfer Objects, I used the same instrumented POJOs. It worked, but I had to put in my remote client the Hibernate jars, and I had to be cautious using lazy fetching of data. But it worked.
Now we have started a project with a mid-term roadmap, and we are going to use the new EJB3 spec on JBoss Application Server. One of the requirements is that maybe in a not so near future, the web layer is going to be physically placed in a different server. So we tried to use EJB3 entities as Transfer Objects. And… Surprise! We found out that the EJB3 Entities are instrumented Hibernate objects! So we had to put the Hibernate libraries in the remote TOMCAT client in order to work.
I was a bit surprised, and I posted this message in the JBoss.com – Forums – Attaching and detaching EJB3 Entities asking for some help (JBoss guys answer promptly), and the answer was: ‘Put the hibernate jars in the client’. Ok… Thanks a lot… But… Is this what the specification says? If you read the specification in Chapter 3.2.4 ‘Detached Entities’, it is not clear if it’s mandatory to implement the Entities marked with fetch=EAGER without any kind of manipulation: The application may access the available state of available detached entity instances after the persistence context ends. If you are using POJOs, and you are not using Hibernate explicitly, why do I need the Hibernate jars?
This problem has arisen too in the Glassfish project, and some people have suggested to implement some kind of transparent detaching of the POJOs before serialization. I think this is something the specification lacks of, and should be updated in order to fix this annoying problem.