Blog/Three abstractions

Three abstractions and nothing else

There is a kind of framework complexity that gets mistaken for power. If the model does not fit on a whiteboard, you will meet the rest of it in a debugger. ST/ORM has three user-facing concepts, and they cover the whole thing.

February 17, 2026Design4 min read

Entity

The data your application works with. A Kotlin data class or a Java record with a couple of annotations, @PK for the primary key and @FK for a foreign key. ST/ORM connects entities to tables and columns by convention, so annotations show up only where the convention does not fit. An entity carries no hidden state and no behavior. It is database-backed data as a plain value, and nothing else.

Repository

CRUD operations and type-safe queries for one entity. You define an interface and write the query method bodies with the DSL. There is no method-name parsing that turns findByStatusAndCreatedAtAfter into a hidden query, and no generated query you have to reverse-engineer from a log. If a repository runs a query, you wrote it, and you can read it.

SQL Template

Direct access to SQL with type-safe binding and result mapping, for when the DSL is not the right tool: joins, reports, database-specific features, or queries where SQL should stay SQL. It sits beside the DSL rather than under it; reaching for it is a choice, not a failure. Type references and metamodel columns keep it checked; parameters are bound automatically. It follows the case for keeping SQL in view rather than hiding it.

Why a small model is the point

There is more underneath, of course: transactions, a static metamodel, change detection, generated code. It is all there to support these three, not to add a fourth concept you have to learn.

These three share one principle: nothing happens that you cannot see in the code. No query fires that you did not write, the SQL each one produces is predictable, relationships load when you ask for them, and transaction boundaries are declared rather than inferred. In practice that means you can teach the whole model to a new engineer in an afternoon, and you never have to reconstruct what the framework decided to do on your behalf.