ORM: runtime proxies vs bytecode instrumentation

hibernatejpaorm

What are the benefits of using runtime proxies with an ORM provider like Hibernate or EclipseLink compared to bytecode instrumentation/enhancement?

I know that bytecode instrumentation helps to optimize dirty checking. Because it can intercept modifications, ORM provider doesn't need to traverse all the objects in the persistence context and compare the current values with the snapshot taken when the objects were loaded (thus avoiding additional memory consumption as well, I assume).

Also, I know that it can help in situations in which additional queries have to be executed because the ORM provider doesn't know whether a proxy needs to be created or what the primary key value in the proxy is, like in lazy one-to-one associations, thus making the associations effectively eager in some situations.

Some other proxy pitfalls have been described in this blog, like direct field access (in equals and hashCode methods) and using of instanceof operator.

It seems to me that bytecode instrumentation is a better alternative. Does it have any pitfalls of its own compared to runtime proxies approach? Is there any rule of thumb which should be followed when choosing one instead of the other?

Best Answer

Both Hibernate and EclipseLink use the Proxy design pattern to implement lazy/eager loading of entity relationships. Proxies are weaved into Java bytecode at build time (statically) or at runtime (dynamically) - basically enhancing your Entity POJOs. Other features, such as dirty checking are also weaved into bytecode.

This is an application of Aspect Oriented Programming (AOP). All the same pitfalls (e.g. unexpected classes at runtime) and advantages (e.g. cleaner source code, runtime code injection) apply.

So the question is, what are the alternatives? You could disable weaving and implement the same features (lazy loading, dirty checking, etc.) in your own code - no runtime surprises, but increased development effort.

As a rule of thumb, use annotations, avoid runtime entity class inspection and trust Hibernate or Eclipselink code weaving to deliver what you want. Note that you always have the option to implement your own proxies, etc. if complexity requires it.

Related Topic