You can make it work. But I think Hibernate and other ORMs work by selling you on the notion that they're an abstraction, that you don't have to know everything to use them. In my experience, Hibernate winds up creating a third domain of necessary expertise, rather than managing the two so you only have to have one. And this is the source of the anger.
Despite being very much an app developer myself, not a DBA or particularly a DB development guy, I've seen DBs outlast many apps, coding languages etc, and always feel it's the most important thing at the end of the day.
Depends on your domain too I guess, I'm sure there are many important exceptions.
For example, prepared statement for update looks like this:
PreparedStatement ps = ...;
ps.setLong(1, author.getUserId());
ps.setLong(2, author.getStreamId());
ps.setString(3, author.getNetwork());
ps.setString(4, author.getIdInNetwork());
ps.setString(5, author.getNote());
ps.setString(6, author.getSocialId());
....And manually counting questions is a normal practice when you add a field:
static final String UPDATE = "UPDATE Table1 SET Domains = ?, TemplateId = ?, InternalJson = ? WHERE StreamID = ?";
static final String INSERT = "INSERT INTO Config1 (UserID, StreamID, Domains, TemplateId, InternalJson) VALUES (?, ?, ?, ?, ?)";Another example is trying to depend on CASCADE in the database. The settings you need to make to get Hibernate to accept this are quite arcane and force you to manually worry about list indexes in the Java code. Yet another example of a place where Hibernate, which ought not be telling me how to make my database or my Java code, instead winds up forcing me to take certain decisions in both.
Pretty sure ibatis helps you avoid the counting ? chars by naming params in a #param1# syntax, might be mis-recalling though.