How to enable load time / runtime weaving with Hibernate JPA and Spring Framework
hibernate, hibernate-entitymanager, jpa, load-time-weaving, spring
Solution
After considerable reading of code and debugging, I figured this out. It's a shame the Hibernate ORM documentation doesn't include this information. (To be fair, the Hibernate EntityManager documentation does, but it's not easily found. The Hibernate instructions on "Using lazy property fetching" only says, "Lazy property loading requires buildtime bytecode instrumentation." It does not mention that you can use runtime instrumentation with a Hibernate EntityManager property.)
The first thing you must do is set the `"hibernate.ejb.use_class_enhancer"` JPA property to `"true"` (`String`). This tells Hibernate that it may use the "application server" class transformation by calling `addTransformer` on the `PersistenceUnitInfo` instance. The "application server" class transformation is really Spring's `LoadTimeWeaver`. If you are using Spring's Java configuration and `LocalContainerEntityManagerFactoryBean`, and Hibernate is a compile-time dependency, you could use the `AvailableSettings.USE_CLASS_ENHANCER` constant instead of the string-literal `"hibernate.ejb.use_class_enhancer"` (which would make it typo-resistant).
If you are using Spring's Java configuration, there is an additional step you must take until SPR-10856 is fixed. `LocalContainerEntityManagerFactoryBean`'s `setLoadTimeWeaver` method is not called automatically like it should be, so you must call it manually. In your `@Configuration` class, just `@Inject` or `@Autowire` a `LoadTimeWeaver` instance and call `setLoadTimeWeaver` manually when you are creating the `LocalContainerEntityManagerFactoryBean`.
With these steps taken, I'm now using Hibernate's runtime entity bytecode instrumentation with Spring Framework in Tomcat.
Problem
I'm using Hibernate as a JPA provider (I'm using its `EntityManagerFactory` instead of its `SessionFactory`) in a Spring Framework application. I managed to get Spring Framework's load time weaving support working, so I'm past that hurdle. I need to enable lazy loading of `byte[]` and `@ManyToOne` properties on an entity. I understand how to instrument (weave) my entities at build time using Hibernate's ant task, but I'd like to instrument my entities at runtime instead (load time weaving). I've seen references to in on several Google search results, but no actual instructions for enabling it. What property do I need to set to instruct Hibernate that it can instrument my entities at runtime?