Hacker News new | ask | show | jobs
by Dragory 2113 days ago
It seems you cannot load relationships for a collection of entities easily without N+1 queries, unless I'm missing something. Based on the many-to-many section of the docs (https://github.com/Seb-C/kiss-orm#many-to-many), I would have to load relationships for each entity separately, and then if they have further nested relationships, run a query for each again. The subsequent section also mentions eager loading is not supported.

For me, being able to load relationships (and especially nested relationships) with little boilerplate and few queries is probably the most useful feature in an ORM (usually explicitly eager-loaded), so I'm sad to see it's not supported.

2 comments

Implementing eager-loading with the current philosophy of kiss-orm would be tricky and difficult to use/read. It did not seem a high-priority, so I chose to not implement it for now.

Depending on the ORMs, the definition of eager-loading also varies.

I have seem ORMs doing everything in a single query, returning everything in a single result-set and then de-duplicating everything client-side. This is very messy (and impossible to hack/fix most of the time).

Currently, the way to go would be something like this:

    const articles = await articlesRepository.search(sql`
        "authorId" IN (${sqlJoin(
             users.map(user => user.id),
             sql`, `,
        )})
    `);
    // Dispatch and assign the articles in the collection of users
I could consider having a helper method to make this easier, but I am afraid this would be quite difficult to use.
Agreed on the N+1 query problem, but I'm a bit mystified why people still choose ORMs for any projects with even a moderate level of database complexity. When using a straight SQL layer (JDBC or the basic features of KISS-orm) the query is in SQL form and the performance characteristics of the query are obvious from the query or can be analyzed easily by taking the query and running it through the database's query analysis tools. Using an ORM just adds extra steps: instead of optimizing a query in SQL, the query needs to be optimized using directives or methods or annotations that the ORM provides in the hope that the SQL that is ultimately generated is efficient; that is, we're programming the ORM which programs the database instead of just programming the database. Why bother with the extra step? With modern programming languages there really isn't that much extra boilerplate to implement the DTOs for straight SQL and it usually results in code that is a lot easier to maintain and extend in the examples I've seen.
In my experience, 99% of the relationships I fetch fit the basic one-to-one, one-to-many, many-to-many definitions that pretty much all ORMs support. For these cases, the queries are generally more than efficient enough and there's little reason to reinvent the wheel and implement the code for fetching those relationships yourself.

For anything more complex, I agree. But for the common case of fetching simple and often (depending on your project) nested relations, I definitely enjoy the abstraction provided by ORMs.