The SQL generated by Hibernate is as good or bad as you tell it to; something like inappropriate config causing the n+1 SELECT you describe will instantly show up in any decent dev workflow. You're not bound to JPQL, you can very well use SQL directly too if that benefits your situation.
As any powerful tool, Hibernate ORM requires good knowledge of it in order to use it efficiently and effectively. Use it if you have the problems which it solves; don't use it, if you don't have those problems.
Disclaimer: former Hibernate core team member
I find the the main benefit of ORMs is type safety. Provided you're using the ORMs to also manage your schema (which you really should if you're using an ORM), then the compiler can guard you from a whole class of mistakes. You're also able to change table and column names with trivial effort and without fear of missing updating some SQL query string somewhere and only finding out during runtime that something is wrong.
While it's possible to write LINQ which results in bad SQL, if you didn't have an ORM it would still be possible for developers to write bad SQL anyway. Either way your developers should understand SQL at least a bit and be able to use something like SQL Profiler to ensure that their queries are performant. There is no substitute for competent developers.
There is a performance overhead to Entity Framework in the way it tracks changes to objects in contexts. If you're needing to work with a lot of objects from/to a database, then for these particular use cases you can opt out of some of these convenience features to avoid the performance costs.
ORMs are an incredibly useful tool if the trade-offs make sense for your project and you know how to use them correctly. But as with any tool, if you use it inappropriately, you're going to have a bad time.
Want to know my secret? It's very simple. I just read the manual in 2004.
After using it successfully for so long, I wrote a best-seller about how to get the most out of it:
https://www.amazon.com/High-Performance-Java-Persistence-Vla...
And, just because afterward I even worked on Hibernate to add all sorts of performance improvements to it, it doesn't mean I don't love SQL. In fact, I happen to run a High-Performance SQL training too:
https://vladmihalcea.com/trainings/high-performance-sql/
Your comment is based on a very common misconception that Hibernate aims to replace SQL. If that were true, then why do you think Hibernate has been offering the createSQLQuery (a.k.a. createNativeQuery) since 2002?
Why not save a lot of time and bugs and use a battle tested ORM and drill down to SQL for the queries that really matter instead?
There’s also a middleground where developers learn to use the ORM better. I’ve seem people get terrible performance using the Django ORM, but after a rewrite, redesigning the queries and using the more advanced features performance would improve massively. The problem is that need to be able to write the SQL and then mentally backport to the ORMs syntax.
We’ve had customers complain about poor database performance. When we find the horrible queries generated by their ORM it’s frequently easier for the developer to just request more hardware or ask if we can: “performance tune” the database.
With a query builder, you can still use the database in a type-safe way and without gluing strings together, but accessing the database is also more explicit, so mistakes are harder to make.
It's fine to represent the result of a database query as a sequence, but its type and interface should be different from that of eg. a list datastructure, because it can fail. similarly, if you have "User" objects representing users, it needs to be explicit which methods fetch data from the database and which use only in-memory properties that code may freely access. Preferably, have different types for "UserInDB" and "User" altogether, with some glue to go between them.
There is nothing inherently slow about Hibernate (other than people not knowing how to use a tool and blaming it), and frankly, providing a unified SQL dialect that ports over another DB is a plus.
In practice the developers go overboard with SQL - the native-first SQL actually makes for quite confusing data model. There is value in clarity that limitations of Hibernate model brings or promotes.
With MyBatis approach the underlying DB can contain incredibly bizarre joins, crazy FKs, you find aggregation functions in queries trip you up, massive views used under the hood, triggers make appearance to confuse you, the list just goes on.
(The reason this happens is as years tick by, extra requirements get fitted into SQL model by doing these "clever hacks" and avoiding re-architecting. The kludges pile up, it's done because it's possible to do so, and every little decision seems like fair tradeoff when made in isolation. End result = massive pile of confusion.)
You think staying close to SQL is the salvation, but really it's just another way to hang yourself. I will not argue it's possible to do excellent work, but in no way it's guaranteed.
Hibernate creates appallingly bad SQL, so “databases are slow”. Particularly when using a getter on a lazy-loaded relationship. A query might end up taking 1ms per record instead of 10ms for 10k records.
You can rewrite all you want in Hibernate and greatly improve performance, but you often need to introduce Projections, lazy/nonlazy flags, in the end you program Hibernate more than you would have written basic SQL. Ah, also you’re writing JQL not SQL, so you need to learn “how it’s written in JQL”. But every Java developer is happy, because it’s Java. Phew, at least you didn’t write SQL!
- Any storage, even file or memory storage, can perform better on production than Hibernate.
- Devspeed is much faster without Hibernate. Source: I’m a founder, initiated a few apps, one is on prod making money after 2 weeks, the other one is still losing money after 18 months, guess which one uses React-Spring-Hibernate and which one used jQuery-Freemarker-Dropwizard.
- But if you want competent developers, React-Spring-Hibernate makes you look young and cool.
It’s sad, because frameworks are as difficult as the maximum difficulty our developers can handle, and if they’re not, they will add a layer. Conclusion: People have no love for databases because they’ve put too many layers before them. But they are not the problem.