* They hide the queries. When your DB or cloud service gives you a printout of your 10 slowest queries, you then have to figure out what object code that relates to. And then is there even a way to fix it, or are you stuck with the ORM?
* LINQ-specific: Love the tech, but it's unclear whether my .wheres() are being sent upstream properly, or if I'm downloading the whole database and filtering it in memory.
* Another LINQ one: we wanted to do "INSERT IF NOT EXISTS" but could not.
* Back in Java land, magic like that tends to be incompatible with basic hygiene like consting all your class fields. Frameworks like being able to construct a Foo in an invalid state, and then perform a bunch of mutations until it's in a good state.
* They make it near impossible to reason about transaction states. If I call two methods under the same open db context, what side-effects can leak out? If I try to do an UPDATE ... SET x = x + 1, that will always increment correctly in SQL. But if read x from an ORM object and write back x + 1, that looks like I'm just writing a constant, right?
* Extra magic: if you've read a class from the db, pass it around, and then modify a field in that class, will that perform a db update: now? later? never?
But just in general, I want to look at the data, play with queries in a repl environment until they look right, and then use directly in the code without needing to translate from high-level&declarative down into imperative loops, sets and gets.
This is not specific to ORMs... you can run into the same problem without one.
> Extra magic: if you've read a class from the db, pass it around, and then modify a field in that class, will that perform a db update: now? later? never?
In every ORM I've used you have specific control over when this happens.