I think this discussion here is good. Whether it be an ORM or something like JOOQ it is always a tradeoff. I've found that the main pain point for me with these technologies is, that in any relatively complex project, you might want to query a similar but not identical thing in different ways. For either performance or business logic reasons. So lets say you have a POJO (in the Java world), that has a bunch of annotations on it. Once you need 3 different ways to query the same thing in different contexts, that breaks down. It also hides the database layer and structure from you, that you are in fact dealing with tables, not a hierarchy of objects, which can be misleading (especially to less experienced developers). We ourselves have gone the following route: All SQL is written as SQL (We use MyBatis for interfacing with that). And the only real features we use, are mapping and flow control constructs/loops for batch data. It is a lot more writing in that sense, but it also means that the query you write is the exact same one that gets executed. As for writing some database agnostic SQL, that can be executed on all of the big 3 (Oracle, Postgres, MySQL) - I have literally never seen anyone need that in practise. It also prevents you from optimizing to database specific features (in case of postgres, CTE is a good example).