deepkit-framework
deepkit-framework copied to clipboard
Nested joins on backreferences are not deserialized properly
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);
});
This should be fixed with the latest join fixes/improvements