I beg to disagree. I don't know what your dev env is, but any ORM will cause dynamic table / column labels. This isn't a bad thing. This means you don't spend countless hours hand sculpting selects/updates.
- Considerably faster to write and maintain queries / persistence
- Significantly less code / DB coupling
- Makes DB refactors easier to handle (depends on how much you leverage static DB-metamodels but that's another discussion)
- Eager/lazy fetching makes foreign relations stupidly easy, like legitimately night and day
- Often less efficient because its harder to pull in subsets of a table row vs. just fetching full rows (though totally doable, people generally don't bother)
- Depending on the SQL abstraction, you can get some bad JOIN's if you don't know the gotcha (but these are generally poorly constructed large queries, but they do require debugging to fix)
- Eager/lazy fetching can cause SIGNIFICANT poor performance if you aren't aware of what your queries / related code are doing
If you want to know what's being pushed into the DB, put in breakpoints into the ORM layer or add persistence listeners to trace what's being stored / when (then turn it off for prod). If you're using raw JDBC, you don't have no excuse for traceability. Your problem isn't in the language, its about your ignorance about the framework / libraries your project is using.
Plus, at least with Hibernate, it'd use bind variables, not poor performing literals unless your code itself is being written with native SQL queries in JDBC. The one thing not trivially easy in most ORM's is DB-side batch updates. I generally hand code my SQL in those cases, but it can be done.
Don't blame a language for the mistakes of the developer. Don't blame the language for 'selecting bad developers'. Blame underperforming developers for underperforming, or blame management for not managing / training / filtering them very well.