For java developers, what is better than Hibernate?

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.


I agree with others that the notion of better is subjective and context-dependent. True alternatives to JPA / Hibernate are:

MyBatis

It is the most popular SQL templating engine in Java. It externalises SQL statements into XML files, from where they can be loaded by ID or by other means. As a templating engine, MyBatis also supports SQL composition and a slim templating language for loops and branch statements.

jOOQ

This is a popular SQL DSL allowing for typesafe construction of SQL statements directly in Java. Unlike MyBatis, this library encourages embedding SQL in Java, instead of externalising it. (Disclaimer, I work for the vendor)

Other alternatives...

... include SQL-string-centric libraries that ease some of the pain when operating with JDBC directly:

  • JdbcTemplate
  • Apache DbUtils
  • JDBI
  • sql2o
  • persism

Hibernate and other ORMs are designed to make RDBMSs work with object oriented applications. If you are not forced to use an RDBMS I would simply use an ODBMS.

Many ODBMS support implicit lazy-loading via byte-code enhancement, so it is almost impossible to write code that accesses an object that is not properly loaded. You can usually also specify (per code-path) closures that load objects not one-by-one but in batches, which improves performance.

Some ODBMS are:

  • db4o (free, pure Java, but less powerful)
  • Versant (powerful, commercial, Java frontend, C/C++ backend)
  • ObjectStore (commercial)
  • Objectivity (commercial)

ODBMS are sometimes frowned upon, but (in my experience) never by people that have actually used them. I have ODBMS in small and large projects (up to 10TB and 2.000.000.000 objects) and I would never go back to RDBMS.