ProvenPin Install

MikroORM 7 entities and Unit of Work on SQLite: working versions (tested 2026-10-15)

Define MikroORM 7 EntitySchema models with OneToMany relations, persist through the Unit of Work, and query with populate on an in-memory better-sqlite3 database.

passed1 passed · 0 failed2026-10-15 16:02 UTC
Status
passed
Last passed
2026-10-15 16:02 UTC
Tests
1 / 1
Language
TypeScript
Runtime
node v22.23.3
pinned versions4
@mikro-orm/sqlite@7.2.5better-sqlite3@13.0.3tsx@4.23.15@types/node@26.6.5
run it
npm install --no-audit --no-fund --ignore-scripts=false
npm test
test environment
node v22.23.3
linux 6.17.0-1022-azure
x64
runner: github-actions 38764699834

The code

Exactly the files that passed. Your agent can pull them with get_recipe("mikroorm-sqlite-entities") (install), or see them on GitHub.

package.json
{
  "name": "mikroorm-sqlite-entities",
  "private": true,
  "type": "module",
  "scripts": {
    "test": "node --import tsx --test test/*.test.ts"
  },
  "dependencies": {
    "@mikro-orm/sqlite": "7.2.5",
    "better-sqlite3": "13.0.3"
  },
  "devDependencies": {
    "tsx": "4.23.15",
    "@types/node": "26.6.5"
  }
}
src/entities.ts
import { Collection, EntitySchema, type Ref } from "@mikro-orm/sqlite";

export class Author {
  id!: number;
  email!: string;
  books = new Collection<Book>(this);
}

export class Book {
  id!: number;
  title!: string;
  author!: Ref<Author>;
}

export const AuthorSchema = new EntitySchema<Author>({
  class: Author,
  properties: {
    id: { type: "number", primary: true, autoincrement: true },
    email: { type: "string", unique: true },
    books: { kind: "1:m", entity: () => Book, mappedBy: "author" },
  },
});

export const BookSchema = new EntitySchema<Book>({
  class: Book,
  properties: {
    id: { type: "number", primary: true, autoincrement: true },
    title: { type: "string" },
    author: { kind: "m:1", entity: () => Author, ref: true },
  },
});
src/db.ts
import { MikroORM, defineConfig, ref } from "@mikro-orm/sqlite";
import { Author, AuthorSchema, Book, BookSchema } from "./entities.ts";

export async function createOrm() {
  const orm = await MikroORM.init(defineConfig({
    entities: [AuthorSchema, BookSchema],
    dbName: ":memory:",
    allowGlobalContext: true,
  }));
  await orm.schema.create();
  return orm;
}

export async function addAuthorWithBooks(orm: Awaited<ReturnType<typeof createOrm>>, email: string, titles: string[]) {
  const em = orm.em.fork();
  const author = em.create(Author, { email });
  for (const title of titles) em.create(Book, { title, author: ref(author) });
  await em.flush();
  return author.id;
}

export async function listBooks(orm: Awaited<ReturnType<typeof createOrm>>, email: string) {
  const em = orm.em.fork();
  const author = await em.findOne(Author, { email }, { populate: ["books"] });
  return author?.books.getItems().map((b) => b.title).sort() ?? [];
}
test/db.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import { addAuthorWithBooks, createOrm, listBooks } from "../src/db.ts";

test("persists author books and populates", async () => {
  const orm = await createOrm();
  await addAuthorWithBooks(orm, "[email protected]", ["Dispossessed", "Earthsea"]);
  assert.deepEqual(await listBooks(orm, "[email protected]"), ["Dispossessed", "Earthsea"]);
  await orm.close();
});

Connect to ProvenPin

Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.

terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp

Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.