Choosing Hibernate when your Java code interacts with SQL databases is widely considered the default choice. We however use the JOOQ code generator instead. Here are some of the reasons why we think it's a better choice.

Schema Definition

In an ideal case, you write the schema for your database in native SQL dialect, using all of your database's special features. The language-specific code is then generated off of that schema. This is what JOOQ does.

With an ORM, you end up defining your schema in Java-specific 'entity' classes using a whole bunch of annotations.  Not only do you give up on any special features of your database's DDL, but you also now have to learn this Hibernate specific Annotation-based DSL to define your schema. It's the worst of all worlds.

Transparent SQL

You want the SQL statement being sent to your database as explicit and transparent as possible. ORMs turn this dial the opposite way. Many times one has to turn on debug level logging just to see what SQL statements are being generated by Hibernate code. Things like when a foreign key reference in an entity is causing data to be loaded lazily or not can be very opaque.

Not to mention, advanced database-specific functionality, like Common Table Expressions, can be tough to use with Hibernate and will probably require you to fallback to hardcoded SQL strings anyway.

JOOQ generated classes allow you to write code that looks exactly like the SQL being generated while still being type-safe. This gives you the type safety of Java while providing transparency into the query and not needing you to learn a whole new annotation-based DSL.

CRUD classes

The one place where ORMs shine is doing simple CRUD operations. In this case, just assigning some fields to an object and calling .save() on it is far simpler than manually generating INSERT statements. Similarly for doing simple SELECTs. JOOQ acknowledges this and also generates basic entity classes for each table that allow you to do the simple CRUD operations easily.

Conclusion

The object-relational impedance mismatch has been a subject of much debate with ORMs like Hibernate. We think JOOQ takes the right approach to solving this problem. We wish JOOQ also generated code for languages other than Java.