deepkit-framework icon indicating copy to clipboard operation
deepkit-framework copied to clipboard

Nested joins on backreferences are not deserialized properly

Open timvandam opened this issue 2 years ago • 1 comments

The query is correct, but the result is not added to the deserialized entity. It works fine for nested joins on regular references. It breaks when you have a reference and then a backreference

Test suite:

import { Database } from '@deepkit/orm';
import { SQLiteDatabaseAdapter } from '@deepkit/sqlite';
import { AutoIncrement, BackReference, PrimaryKey, Reference } from '@deepkit/type';

class Entity1 {
  id: number & AutoIncrement & PrimaryKey = 0;
  constructor(public entity2: Entity2 & Reference, public entity3: Entity3 & Reference) {}
}

class Entity2 {
  id: number & AutoIncrement & PrimaryKey = 0;
  entity3s?: Entity3[] & BackReference;
}

class Entity3 {
  id: number & AutoIncrement & PrimaryKey = 0;
  constructor(public entity2: Entity2 & Reference) {}
}

const db = new Database(new SQLiteDatabaseAdapter(':memory:'), [Entity1, Entity2, Entity3]);
db.adapter.connectionPool.maxConnections = 0; // this is actually 1 due to an off by one (#369)

const a = new Entity2();
const b = new Entity3(a);
const c = new Entity3(a);
const d = new Entity1(a, c);

beforeAll(async () => {
  await db.migrate();
  await db.persist(a, b, c, d);
  db.logger.enableLogging();
});

// fail: entity3s is empty array
it('should populate nested inner joins (backreference)', async () => {
  const d = await db
    .query(Entity1)
    .useInnerJoinWith('entity2')
    .innerJoinWith('entity3s')
    .end()
    .findOne();
  // logged query DOES properly inner join and select entity3s

  expect(d.entity2.entity3s?.length).toBe(2);
  expect(d.entity2.entity3s).toContainEqual(b);
  expect(d.entity2.entity3s).toContainEqual(c);
});

// fail: entity3s is empty array
it('should populate nested left joins (backreference)', async () => {
  const d = await db.query(Entity1).useJoinWith('entity2').joinWith('entity3s').end().findOne();
  // logged query DOES properly left join and select entity3s

  expect(d.entity2.entity3s?.length).toBe(2);
  expect(d.entity2.entity3s).toContainEqual(b);
  expect(d.entity2.entity3s).toContainEqual(c);
});

// pass!
it('should populate nested inner joins (reference)', async () => {
  const d = await db
    .query(Entity1)
    .useInnerJoinWith('entity3')
    .innerJoinWith('entity2')
    .end()
    .findOne();
  expect(d.entity3.entity2.id).toBe(a.id);
});

// pass!
it('should populate nested left joins (reference)', async () => {
  const d = await db.query(Entity1).useJoinWith('entity3').joinWith('entity2').end().findOne();
  expect(d.entity3.entity2.id).toBe(a.id);
});

timvandam avatar Sep 10 '22 19:09 timvandam

This should be fixed with the latest join fixes/improvements

marcj avatar May 07 '23 17:05 marcj