You know the story - you start programming and you find yourself in need of a data store - place to keep and lately, hopefully, retrieve your precious data. You already know some Java, HTML, CSS, probably JavaScript as well and now you here comes the database. You've got several options so you start choosing - NoSQL, SQL or something else. Modern developers pick NoSQL for sure, they just want to save data and after us, the deluge. I'm going to skip it as I truly belief that NoSQL will eventually become a marginalized minority as it was several years back.
When it comes to SQL you start to have a dilemma. You'd like to access the database in an object way however there's this hairy old SQL language which doesn't do objects. So your first instinctive thought is to start using ORM - and nowadays Hibernate is a synonym for ORM.
It goes all so well. You define your data objects, you let Hibernate to generate your database schema - happy days. You can query for objects, create, modify and delete them and it's all so rosy.
But in a while - problems. Transactions not working as expected, relations are not propagated the way you want them to, database becomes slow and keeping the application running a chore. And after a bit longer you start to be more and more unhappy with your choice.
So what's wrong with ORM?
First of all ORM adds an extra level of complexity. You have to define stuff and obviously ORM brings in additional extra megabytes of code. And this comes at price. Application start up time up, performance down, scope for errors even higher. Hibernate uses black magic to get lots of things done so you find your object and method proxied, AOPed and intercepted. And that's not all.
ORM encourages bad practices and accesses database in an uncontrolled way - instead you taking control of the database you may not even know what tables there are!
Later you figure out that optimizing queries is next to impossible. Queries are generated by the ORM framework and you've got only limited way to influence their creation. So things like adding an index can be a nightmare.
And that's not all - ORM gets you more data than you need or you think you get. Not only you can’t specify columns you want to get, you may also find that you're fancy ORM goes to database for every detail object. I'm talking about this typical scenario where you iterate a collection of details. You either get all eagerly or nothing lazily. But ORM usually has no idea how you want to get the data (and neither do you) so if a detail for a master has 1000 elements you can end up going to database 1000 times. A real performance killer.
And even if you try to optimize that thing you may struggle - ORM makes it hard to optimize DB by adding indexes due to its unpredictability when it comes to construction of SQL queries. You can, normally, dump all the queries but there's no guarantee that the same queries will be generated all the time so it may be difficult to figure what to index and how. It's also a nightmare for your DBAs as generated queries are hard to read and thus optimizing can be a good fun for a couple of weeks.
So it's the old fashioned DAO where your handcrafted SQL lives still a way to go? May be. That's mostly up to you. But either way, you better master those SQL skills as that's the only way to get your database performance where you want it to be.