Such ORMs pretend that data are objects in OOP sense, with internal mutable state stored in their fields. This leads to endless bugs with dirty vs clean state, complicated and bug-prone logic in `.save` methods, hard to debug performance problems with transparent lazy-loading of related objects, and inevitable performance loss on hydration / dehydration of all fields. (I saw and fought this all in practice.)
Better approaches, such as the one available in SQL Alchemy, do not hide the relational nature of the data. They allow to `select` arbitrary tuples, and, most importantly, to build queries from composable, reusable parts.
ORM is not the best interface to an RDBMS. But a good, ergonomic interface to an RDBMS is a very important and useful thing.
All that was missing was an ORM. Annotation-based, no less. Java devs have made very painful experiences with those. For good reasons (that are easy to google)
What you gained was giving a type name to a collection of attributes and describing relationships between them. What you lost was the ability to treat the data coming from the database as - well - data. You just put it into a straight jacket (classes).
Your saving grace is a `toData()` function ;)