Ask anyone what the M stands for and they answer mapping, a translation between relational data and typed values. Then watch what the tools wearing the name actually do all day.
Read the term literally. On one side you have tables, rows, keys. On the other side, the types and references of your language. Mapping is the translation between the two, and it goes both ways. Reads turn rows into typed values. Writes turn values back into statements, in the right order, with generated keys ending up where they need to go.
That work is not trivial. Hydrating results, deduplicating repeated rows, ordering writes by their dependencies, batching, key propagation. All of that is real work, and any serious mapper has to do it. But none of it requires your objects to have a lifecycle.
Nothing in the name mentions a session, a proxy, or a flush. That machinery has its own name: management.
By management we mean something specific here: a persistence context that outlives individual operations and holds your entities inside it. The context tracks which objects are attached, watches them for mutation, keeps an identity map across operations, stands proxies in for rows you have not read yet, and decides at flush time which of your changes become SQL, and in what order.
In other words: a stateful runtime that owns your objects between statements. To be clear, short-lived coordination inside a query or a write is just the job. The criticism is about the long-lived kind.
The history is worth getting right. TopLink was doing identity maps and units of work in the nineties. Hibernate arrived in 2001 and made that persistence model the default mental image of the word ORM. Fowler catalogued the underlying patterns in 2002: Data Mapper, Unit of Work, Identity Map, Lazy Load. JPA later standardized a lifecycle and API in the same family. After twenty years of that, the M might as well stand for management.
Listen to the standard complaints with that in mind. N+1 queries usually trace back to implicit lazy loading of associations, though nothing stops you from writing one by hand. The LazyInitializationException is a session-lifecycle error by definition. A surprising UPDATE can come from dirty tracking, from a cascade, from relationship synchronization, or from flush timing, and the debugging session looks the same in every case: the mutation happened in one place and the SQL in another. Autoflush makes that gap structural, even where an explicit flush is available.
None of these complaints are about mapping. They are all about management.
Mapping has no comparable list of famous failures. It does not need to hide when database work happens, and hiding is where the resentment comes from. We made a similar point about hidden SQL before.
This is not just a JVM thing, by the way. Every ecosystem with a relational database has ended up at the same fork. You can tell by the vocabulary: the term "micro-ORM" exists because someone had to invent a word for "just the mapping, please".
To be fair, you get real things back. You can walk an object graph as if it were in memory. You configure cascades once instead of ordering writes by hand. Batching happens at flush time without you thinking about it. The managers implement all of this deliberately, and mostly well.
But you pay for it. Your objects now have attached and detached states, plus the ceremony for moving between them. Identity is scoped to the context, so equality across contexts is suddenly something you have to design for. The moment a change becomes SQL is the flusher's decision unless you step in. And the failure modes have their own names, which is rarely a good sign for an abstraction.
There is nothing wrong with an ORM that also manages. We reached for one by default for years. But management is like many conveniences in life: convenient, until it isn't, and with a growing model that moment tends to arrive in production. The problem is the label: the word says mapping, but what you usually get is management.
The fair question is whether mapping alone gets you far enough. It does, but you have to take both directions seriously. In ST/ORM, a three-table join hydrates into immutable nested values, an owner holding its pets, with repeated rows resolving to the same instance by primary key during hydration: the useful half of an identity map, without the lifetime. A write set runs the translation the other way: hand it a mixed collection of values and it partitions them by type, orders the types by their foreign key dependencies, writes each level as a batch, and propagates generated keys into the rows that reference them. Updates skip unchanged rows by comparing the value being written against the value observed in the same transaction. There is no attach, no merge, no dirty-tracked entity waiting for a flush.
None of that requires a manager. It requires a good translator.
If you sort tools by what they do instead of what they call themselves, you get three groups. Persistence-context ORMs: Hibernate and JPA, and the entity layers that follow their model. SQL-shaped query tools and row mappers: jOOQ, JDBI, MyBatis, which translate queries and results but stop short of graph persistence; jOOQ pointedly declines the ORM label, and the refusal is reasonable. Then sessionless graph mapping, which is precisely where ST/ORM sits.
The point is not to police who gets to use the word. The extras are real features and choosing them is not a mistake. All we are saying is that ORM should not be a word you avoid just because you do not want those features. You should get to want one without the other.
ST/ORM maps objects. It does not manage them. That is not a diminished ORM. It is exactly what the letters spell.