Tags
Authors
Every time we benchmark and profile one of our Hibernate projects for whatever reason we can always count on our good old friend — reflection — to show up and say hello.
Hibernate projects work with user-defined Java objects. Hence, all these projects need a way to read and update fields and create new instances of such objects. Java Reflection can do this, but is it always the best approach? As most abstractions there are downsides to it. It can introduce some unnecessary performance overhead and extra checks/behaviour that may not be required for our use cases. It can also make performance flamegraphs noisier (that is where we have seen it!). Each project is still left to deal with JPMS access rules and member access conventions on its own. On top of that, reflection requires extra configuration for native builds. On the other hand, reflection is a standard JDK API, is simple enough on the surface, and has stood the test of time. Can we do any better than that?
This is certainly not a new problem, and it is not the first time we asked these questions of ourselves. Over the years, each project was experimenting within their own codebases in isolation to find a suitable approach. Solutions we came up with were either partial, not easily shareable with no simple way of plugging an alternative implementation, and some just not suitable because they were tailored to work with certain access patterns. Yes, this matters because the best-performing approach depends on the task — for example, traversing a validation graph versus loading database results into entities.
In an attempt to solve this, we started Hibernate Accessor — a unified state access engine designed to eliminate unnecessary reflection overhead and provide solution for specific access patterns across the whole Hibernate project portfolio.
In this series we will take you through the journey starting from giving you an idea why existing JDK APIs do not solve the problem for us, then walk you through hidden surprises and tricks of bytecode generation and JPMS as well as some of its shortcomings. We will show you how and what we have benchmarked to select a good default all-rounder solution, and finishing the series by exploring what shifting code generation to the build time can achieve and how do we plan to leverage that.
We just published Hibernate Validator 9.2.0.Beta1, the first release of the new 9.2 series of Hibernate Validator.
This release brings a wide range of new constraints, including password validation, a new bean resolution system for integrating application services, configurable property access, performance improvements and bug fixes.
[ ... ]
Hibernate 8.0.0.Beta3
Hibernate ORM 8.0.0.Beta3 is now available.
Coming just a few days after Beta2, the third beta of Hiberante ORM 8.0 is a bit lighter than usual.
Compared to Beta2, notable changes include:
Hibernate 8.0.0.Beta2
Hibernate ORM 8.0.0.Beta2 is now available
The second beta of Hibernate ORM 8.0 brings stronger concurrency guarantees, expanded Jakarta Persistence 4 support, and substantial improvements to migration from legacy XML mappings. It also introduces more convenient configuration options and clarifies the contracts available to integration and dialect providers.
Highlights include:
In our previous post,
we showed how @Mutability(Immutability.class) and removing CascadeType.MERGE cut our JSON processing time in half by eliminating unnecessary dirty-checking.
That was the first round of optimization. This post covers the second round enabling Hibernate’s second-level cache on the same entity, and the surprising
discovery that three annotations must work together to unlock the full benefit. Getting two out of three still left us over 8x slower than the final result.
Hibernate 8.0.0.Beta1
ORM 8.0.0.Beta1 has just been released -
-
Implements support for Jakarta Persistence 4.0 - all features defined through the M5 release are supported and both the Jakarta Persistence and Jakarta Data TCKs are passing
-
Graph-based flushing
-
Row-level secuity with discriminator multi-tenancy
-
Flush-time bidirectionality management
-
Much more
Details about the release can be found at https://github.com/hibernate/hibernate-orm/releases/tag/8.0.0.Beta1.
When we profiled our application’s data import pipeline, we expected the bottleneck to be in our business logic — JQ filters, JavaScript evaluation, recursive SQL queries. Instead, Hibernate’s internal JSON handling consumed over 50% of CPU time and allocated 20 GB of unnecessary objects during a routine import of 5 records.
Two small annotation changes fixed it. No code changes, no architectural redesign — just telling Hibernate what it needs to know about how our application uses its data.
Hibernate Reactive 4.4.0.Final is now available.
Hibernate Reactive 4.4.0.Final is compatible with Hibernate ORM 7.4.0.Final, and Vert.x SQL client 5.0.12.
If you need a Hibernate Reactive version compatible with older Hibernate ORM releases or Vert.x releases, you can find a compatibility matrix on the Hibernate website.
We just published Hibernate Search 8.4.0.Final.
Compared to the previously released 8.4.0.CR1, this version is mostly identical, and only adds a few changes to adapt to the final release of Hibernate ORM 7.4.0.Final and improve the Hibernate Search ORM mapper integration.
Hibernate 7.4.0.Final
Hibernate ORM 7.4 Final has been released.
Details about the release, as well as links to important resources, can be found at https://github.com/hibernate/hibernate-orm/releases/tag/7.4.0.
Some of the new features include -