Spring Load-Time Weaving
Are you struggling with performance issues in your Spring, Jakarta EE, or Java EE application?
What if there were a tool that could automatically detect what caused performance issues in your JPA and Hibernate data access layer?
Wouldn’t it be awesome to have such a tool to watch your application and prevent performance issues during development, long before they affect production systems?
Well, Hypersistence Optimizer is that tool! And it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, Micronaut, or Play Framework.
So, rather than fixing performance issues in your production system on a Saturday night, you are better off using Hypersistence Optimizer to help you prevent those issues so that you can spend your time on the things that you love!
Introduction
In this article, we are going to see how Spring load-time weaving works so that you can apply the Hibernate bytecode enhancement mechanism at runtime.
Traditionally, the bytecode enhancement mechanism is applied when the project is built using a Maven or Gradle plugin. For more details about the build-time approach, check out this article.
Domain Model
Let’s consider we have the following Attachment entity that has a content property that is mapped as follows:
@Lob @Column(columnDefinition="BLOB") @Basic(fetch = FetchType.LAZY) private byte[] content;
The content property is using the FetchType.LAZY fetching strategy, but loading entity attributes lazily cannot be done on POJO entities, so we need the Hibernate bytecode enhancement mechanism to achieve this goal.
Hibernate Bytecode Enhancement Mechanism
The Hibernate bytecode enhancement mechanism allows us to change the bytecode of a JPA entity so that we can intercept the getter and the setter method calls in order to:
- load attributes lazily
- record entity modifications
Most often, the bytecode enhancement mechanism is configured via a Maven or Gradle plugin, which enhances the entity classes when the project is built, as explained in this article.
However, this is not the only approach we can use since we can also instrument the JPA entity classes at runtime when the project is bootstrapped.
Spring Data JPA Load-Time Weaving
To enable the runtime bytecode enhancement mechanism when bootstrapping a Spring application, you have to add the @EnableLoadTimeWeaving annotation to your Spring configuration:
@EnableLoadTimeWeaving
public class BytecodeEnhancementConfiguration {
...
}
Now, we need to provide the Spring Instrumentation library to the JVM via the javaagent argument. If you’re using Windows, you could do it like this:
-javaagent:%M2_REPOSITORY%\org\springframework\spring-instrument\%SPRING_VERSION%\spring-instrument-%SPRING_VERSION%.jar
That’s it!
Testing Time
When loading an Attachment entity and accessing the content property:
Attachment book = attachmentRepository.findById(1L).orElseThrow(null);
LOGGER.debug("Fetched book: {}", book.getName());
assertArrayEquals(readBytes(bookFilePath), book.getContent());
We can see that the content column is not fetched by the first SQL query, being fetched on demand in a secondary SQL query:
SELECT
a.id,
a.media_type,
a.name
FROM
attachment a
WHERE
a.id = 1
-- Fetched book: High-Performance Java Persistence
SELECT
a.content
FROM
attachment a
WHERE
a.id = 1
Awesome, right?
If you enjoyed this article, I bet you are going to love my Book and Video Courses as well.
Conclusion
Using the Spring load-time weaving mechanism can be very useful if we want to enhance the JPA entity classes without having access to the project build.
The @EnableLoadTimeWeaving annotation tells Spring to register a LoadTimeWeaver bean that will be provided to the JPA EntityManagerFactory to enhance the JPA entities that get loaded, giving us the opportunity to enable the bytecode enhancement lazy loading or dirty tracking mechanisms.







It doesn’t work for me, it says I need special class loader
org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘loadTimeWeaver’ defined in class path resource [org/springframework/context/annotation/LoadTimeWeavingConfiguration.class]:
I tried to run the example as well but got this problem:
That is caused by HHH-18108 which was fixed in 6.5.3, but I don’t see it on Maven Central. I will have to check it again after that release to see if the test is working. If it’s not, it’s because of some Spring or Hibernate bug.