David
David

Reputation: 1032

Is Hibernate ORM compatible with GraalVM native image compilation?

The native image compiler in the GraalVM project has, according to the docs, some limitations with dynamic proxies. Since Hibernate makes extensive use of proxies, can it work normally in a project that is ahead-of-time compiled?

The Quarkus project seems to indicate that it can, but my understanding is mainly on the basis of a Reddit post saying

Hibernate ORM can now work even when compiled as GraalVM native images - just make sure you use Quarkus to build the application.

What if I don't want to (or can't) use Quarkus? Is it possible to compile a native-image application using GraalVM (and the SubstrateVM) that uses Hibernate?

What does Quarkus actually do to enable/support Hibernate?

Upvotes: 8

Views: 2877

Answers (2)

Lubo
Lubo

Reputation: 1847

If you wold to know, what does Quarkus actually do to enable native image be build, read transcript (or watch video) with its creator: https://www.infoq.com/presentations/quarkus-graalvm-sao-paulo-2019/

As I remember:

  • in compile time resolves all annotations lookup and entities resolution
  • prepares some instances with "statically" initialized fields. prepared instances are stored in image and prepared to be just allocated on heap at startup time
  • generate "proxies" in compile time if needed
  • basically Quarkus (as "plugin" for gralvm) does "start your application to the point of time, when it does actually connect to database". Than it takes memory snapshot and embed it into jar/native file
  • Quarkus does also touch some other libraries, which does "forbidden" things (closed world assumptions)

This will enable "hot code reload", which actually restarts whole application in a "blink of an eye" time. It uses less memory and other nice things.

PS: little intro to Quarkus is here: https://www.infoq.com/news/2019/03/redhat-release-quarkus/

Upvotes: 0

Sanne
Sanne

Reputation: 6107

(Disclaimer: I'm one of those who made Hibernate ORM work on GraalVM native images, by creating the Quarkus Extensions. I'm also leading the Hibernate R&D team.)

Thank you for this opportunity in writing up a bit of history :)

Initially we were not using Quarkus as it didn't exist yet.

My initial prototypes were just patching Hibernate ORM and piling up many, many compiler switches to be passed to the native-image tool, hardcoded in bash scripts, until I would get my demo application working.

The problem with that approach is that many such flags actually depend on a combination of internal knowledge of Hibernate ORM, AND specifics of your domain model, your configuration details, and probably more.

I started to document such things but it was getting complex and hairy; not least different aspects depend on each other; also, my demo application was rather simple and things were bound to get more complex with real applications... I don't think we'd be able to write a good document which would both be thourough and "understandable".

An alternative to keep things simple for end users would have been "enable reflection on all these classes as you might use them", but I'm a bit of an optimisation freak and that would have created much larger and bloated binaries, than when only and exclusively including all things your application is really going to need.

So our team decided to write a tool which automates such details instead.. it became a bit of a build tool which analyses your application to figure out the best switches to use. And rather than focus on Hibernate ORM only we created the notion of "extensions" which would know how to pull of the same trick for other libraries too, so that you could benefit from highly optimised binaries from more complex applications using a combination of supported libraries, not just Hibernate.

Clearly that was necessary, as different libraries might have conflicting needs, and the combination of compiler flags for each other library and the end user's code needs to be combined in a single consistent set of compatible flags.

So that's how Quarkus became a thing :)

To see details of how this works, I would recommend reading the guides and the source code:

I also gave a bit of an high level overview of how it works in public talks; there's a good recording from Devoxx UK

My talk discusses Hibernate ORM specifically; I don't have much time to go in details of all the things it does, but it should serve as a good introduction before reading the actual code for details.

What if I don't want to (or can't) use Quarkus? Is it possible to compile a native-image application using GraalVM (and the SubstrateVM) that uses Hibernate?

That's a fair question - it's certainly possible but the Quarkus team would love to know why?

All of the work Quarkus does is mostly build-time only; sure it might be limited at this stage as it's a very young project, but if you need support for anything else it should be easier to contribute to its core (or to its extensions) than to hardcode complex compiler flags in a build script. Not least, the Quarkus community is becoming a good place to discuss how to solve any roadblock one might hit with the Graal limitations.

All most complex patches to Hibernate ORM have been merged in the Hibernate upstream repositories, so all important patches are included in any recent release.

Assuming you want to stay clear from Quarkus (I'd not suggest that, but assuming you want to learn...), you will still need to tinker with reflection rules, and indeed Quarkus is restricting some features, most notably some details are still "work in progress", or stuff which we don't believe people should be using anymore :)

Specifically, neither me and my team mates are a big fan of thread-bound sessions. I wasn't going to implement support for that unless someone would make a good case for it: please open a feature request, or ideally help to make a good case for it and a patch?

Upvotes: 8

Related Questions