H3T

Get H3T | API doc
SourceForge Logo

What problem does H3T solve?

If you use Hibernate in a server and are returning entities to a client in a different process, this framework may be for you. Hibernate allows associated collections and single entities to be marked as LAZY (it's the default for associated collections). When you attempt to access an uninitialized lazy element, Hibernate will use the session associated with the entity to load it for you under the covers. If you attempt to access an uninitialized lazy element in your client, then you will see an exception because your entity is no longer associated with a session. Nor can it be.

H3T will intercept your attempts to access uninitialized lazy elements and load them from the server for you. This will happen as seamlessly as if it were being done by Hibernate on the server.

Can I use it?

H3T hooks into JPA entity annotations (e.g., ManyToOne) to intercept your attempts to access associated elements. For this reason, you need to be using Hibernate 3.0 or above and be using JPA annotations. You do not need to be using EntityManager. Nor do you need to be using JBoss Application Server, or any Java EE container for that matter.

What are H3T's dependencies?

JBoss AOP (tested with 1.5), cglib (tested with 2.1.3), and Hibernate (with annotations).

Isn't transparent remote lazy loading dangerous and evil?

Possibly. This topic even has its own entry in the Hibernate Users FAQ. It's also discussed in the Hibernate forum and mentioned in Hibernate In Action. You should be familiar with the pitfalls of following such a strategy before using H3T.

Does H3T hook into all lazy associations?

No. You have to annotate the associations with org.h3t.RemoteLoad. Sometimes you want to see LazyInitializationExceptions in your client because they are highlighting coding errors (e.g., an association should have been marked EAGER). If H3T were to handle all lazy associations for you then you would never, ever see these exceptions and may miss coding errors.

How does H3T know how to get stuff from my server when it needs to initialize lazy associations?

When you mark an association with the org.h3t.RemoteLoad annotation, you can specify an optional factory parameter. Set it to the class of a custom implementation of the org.h3t.LoadServiceFactory interface. Your implementation should return a reference to an org.h3t.LoadService implementation.

The LoadService interface has methods for loading lazy elements. Normally your implementation (or the implementation that sits on the server, at least) will simply pass through the call to corresponding helper methods in org.h3t.Loader. Note that H3T doesn't care how your implementation of LoadService makes requests to the server. It could be an RMI stub, your own implementation that generates HTTP requests—anything.

If you don't set the factory parameter, then H3T will fall back on its default behavior. To acquire a reference to a LoadService, it will create an InitialContext and look up an object named "ejb/H3T/LoadService". The H3T distribution includes, in its own zip archive, org.h3t.ejb.LoadServiceBean. This is an EJB3 stateless session bean. If you deploy it in your EJB app and provide the client with an appropriate jndi.properties, H3T will work out of the box.

Do I have to do anything special when I run my client?

Yes. You need these VM arguments:

 -Djboss.aop.path=[jboss-aop.xml]
 -javaagent:[location of JBoss AOP jars]/jboss-aop-jdk50.jar
jboss.aop.path should point to wherever you place the jboss-aop-xml file that ships with H3T.

Is there an example?

Yes. Download the source archive and run the "runExample" ant target. It builds and deploys an EAR and then runs a very simple client application, which pulls back entities from the server. When the client attempts to access uninitialized lazy associations, H3T kicks in.

To run this application, you'll need JBoss Application Server. If you don't have 4.0.4GA, you'll need to grab your Hibernate/EJB3 jars from JBoss and drop them into the appropriate H3T lib directories. The jars on the client and server need to match.

You'll also need to modify the properties in build.properties to point to your JBoss installation.