Java – For java developers, what is better than Hibernate?


I am unsure if there is a better way to develop database-backed applications in Java, but I thought I would ask.

There is a lot I like about Hibernate, but there are lots of problems too. Most of them are not that big of deal when you have as much experience with it as I have, but I think the biggest problem that I run into is one-size fits all lazy-loading model. Absolutely hate it – there has to be something better out there… no?

The reason I hate the lazy-loading model is that while it's convenient to specify what is lazy and not lazy in the configuration file, there are many parts of an application that would prefer lazy-loading in one area and no lazy loading in another. If you want to satisfy both parts of the program, you need put up with lazy-loading and manually load entities and their children… and their children… and so on. This is just bloat that doesn't do anything to solve the real programming problems – like the features that get the project done.

It seems that the loading strategy that you want to use should be independent of the mapping information, but this is not possible (as far as I know) with hibernate other than writing the loading inside of your java code.

Another problem I have with the lazy-loading is that it's not easily predictable when you are going to have problems. I often don't discover lazyloadexceptions until I deploy my application into Tomcat.

It feels even more bloated when these exceptions occur from frameworks – like by Jackson calling into a collection that hasn't loaded yet. Or maybe Spring is accessing a property I never asked it to, so it throws a LazyInitializationException anyway – for no reason other than that their framework touches all of my bean properties.

Anyway, because I can't discover these problems during integration tests… when I discover them in Tomcat, I often have to shut down tomcat, make the changes, recompile, reload tomcat, relogin to my application, go back to the page I was at to see if it's fixed – this is truly a massive pain. It takes so long to fix one of these errors. I feel like it's just getting in the way of what I am actually doing.

In the end, I just feel that details like this really weigh me down. When I look at my day and ask, "What did I produce today?" – I find problems like this really get in the way of me feeling like I accomplished something.

Of course, I can just turn off lazyloading… but then I get absolutely dreadful performance.

Is there a better way? Something that "just does the right thing", performs well and easier to reason about?


Best Solution

First of, this has nothing to do with Hibernate. Pretty much any ORM (certainly any JPA provider) implements lazy loading in a similar fashion.

As far as "would prefer lazy-loading in one area and no lazy loading in another" goes, you can override lazy fetching via HQL fetch join if you're using queries. For straight up session.get() there's usually no need to do so (Note - see below), you can just let lazy loading do its magic for you. For that to happen you need to ensure your session stays alive until all requests to entity (its properties / collections / etc...) are done, which is typically achieved via Open Session in View pattern. Spring has a corresponding interceptor as well.

Note: One case where you have to load all entity's dependencies is when you're going to ship it to a remote system (thus making original session unavailable). This is typically handled by marshaller, though.