All these negative issues in this readme can be addressed when ORMs like Hibernate are used correctly. And some of the points are outright BS.

Good ORMs make life much easier without compromising on quality and flexibility. Hibernate is more powerful than many developers expect. Many developers tend to see ORMs as magic and don't try to understand the tool they are using.

To comment on some of the points from the readme:

> What you get from Hibernate is not POJOs. Need for DAOs and copy, copy, copy. This is useless code and often breaks. Use generators to generate boiler plate, when possible. Write tests to... test!

If you don't want a data access layer, then don't use an ORM. If you want a layer, you can model everything in a way that does not even expose the fact that an ORM is used.

> Configuration too complex. You end up modelling everything around what works in Hibernate, not your classes (as promised) or what works in the database (that is the real constraint you are facing)

Complex problems tend to have complex solutions. But, I certainly don't find Hibernate hard to configure (these days), even when the data model is complex.

> Hibernate-aware code everywhere

Can (should) be abstracted away. Use interfaces for describing entities and builders. Describe aggregated entities as Aggregates. Model query options as typed parameters. This way, the "boiler plate" becomes the contract for data access, without leaking ANY information about the ORM or whether a relational or non-relational data source / store is used.

> Different query language without a reasonable shell - you have to write code to test out a query

There are IDEs with good ORM support, like IntelliJ IDEA. Otherwise, write a little program or tool that runs the DSL against your code base.

> Very complex and inefficient queries triggered for no apparent reason. You spend a day to control something that would have taken a few minutes in SQL

I've seen complex and inefficient queries written in plain SQL. Usually, the ORM is much better at optimizing, if your data model is sane. If you have statements executed with no reason, then that's probably due to a bad design choice in your application.

> Slow to start - big problem for testing.

ORMs start pretty fast these days. For database initialization, I prefer Liquibase or Flyway over Hibernate's built in initialization.

> Bad practice - if you hide the database, you may get something done quickly, but it's a bad idea. If yor Java code expects to have a collection of one million objects as an array, it does not matter if they are lazily loaded or not - some code somewhere might want to iterate over them, and this will kill the process. You cannot really forget that there is a database somewhere, and you should not do it.

There are streams since Java 8. I use them to stream data from queries (scrollable ResultSet -> Spliterator -> autocloseable Stream). This really helps with the memory footprint. And because I abstract my data source / data store away, the source of the stream can be literally anything. It just happens to be a relational database that is accessed through an ORM.

> Aborts on commit. For long-lived transaction, you never know WHAT made the transaction abort. And what can you do next?

Who the hell event wants long-lived transactions today?!