1. They pretend SQL is standardized, and support a heavily reduced featureset for any given database as a result
2. They leave awkward holes in their abstraction, leading to psychotic behaviors like N+1 and implicit type coercions to helpfully break your indexes silently
3. They make simple queries simple, and hard queries absolutely revolting
4. You end up not wanting to use the objects directly anyways, so you end up with object-object-relation, needing a mapping layer from your database-object to your business-objects, which also defeats most of the benefits from change-tracking
5. The generated SQL is periodically utterly nuts, so you have to review every generated query anyways
6. You probably dont want to actually use any of the OOP mapping features like inheritance in your DB
The correct answer is to use a query builder + database model, enabling most queries to be written with some degree of type-safety, and minimizing the abstraction from SQL itself, and toss out the rest of the featureset