Skip to content

Commit

Permalink
fix(core): fix hydration of relations with custom types via joined st…
Browse files Browse the repository at this point in the history
…rategy

This was resulting in an additional query used by the fallback select-in mechanism, so it wasn't surfacing that obviously.

Closes #5518
  • Loading branch information
B4nan committed May 2, 2024
1 parent f706c06 commit 07f10c8
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/core/src/hydration/ObjectHydrator.ts
Expand Up @@ -174,7 +174,7 @@ export class ObjectHydrator extends Hydrator {
if (prop.customType?.ensureComparable(meta, prop)) {
context.set(`convertToDatabaseValue_${this.safeKey(prop.name)}`, (val: any) => prop.customType!.convertToDatabaseValue(val, this.platform, { mode: 'hydration' }));

ret.push(` if (data${dataKey} != null && convertCustomTypes) {`);
ret.push(` if (data${dataKey} != null && typeof data${dataKey} !== 'object' && convertCustomTypes) {`);
ret.push(` data${dataKey} = convertToDatabaseValue_${this.safeKey(prop.name)}(entity${entityKey}.__helper.getPrimaryKey());`);
ret.push(` }`);
}
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/types/UuidType.ts
Expand Up @@ -12,4 +12,8 @@ export class UuidType extends Type<string | null | undefined> {
return 'string';
}

override ensureComparable(): boolean {
return false;
}

}
72 changes: 72 additions & 0 deletions tests/issues/GH5518.test.ts
@@ -0,0 +1,72 @@
import { Collection, Entity, ManyToOne, MikroORM, OneToMany, PrimaryKey, Property, Ref, types } from '@mikro-orm/sqlite';
import { mockLogger } from '../helpers';

abstract class BaseEntity {

@PrimaryKey({
type: types.uuid,
onCreate: () => crypto.randomUUID(),
})
id!: string;

}

@Entity()
class Product extends BaseEntity {

@Property()
name!: string;

@Property()
price!: number;

}

@Entity()
class Order extends BaseEntity {

@OneToMany(() => OrderItem, e => e.order)
items!: Collection<OrderItem>;

}


@Entity()
class OrderItem {

@ManyToOne(() => Order, { primary: true, ref: true })
order!: Ref<Order>;

@ManyToOne(() => Product, { primary: true, ref: true })
product!: Ref<Product>;

}

let orm: MikroORM;

beforeAll(async () => {
orm = await MikroORM.init({
dbName: ':memory:',
entities: [Product, Order, OrderItem],
});
await orm.schema.refreshDatabase();
});

afterAll(async () => {
await orm.close(true);
});

test('basic CRUD example', async () => {
const product = orm.em.create(Product, { name: 'Product 1', price: 100 });
const order = orm.em.create(Order, {});
order.items.add(orm.em.create(OrderItem, { order, product }));
await orm.em.flush();
orm.em.clear();

const mock = mockLogger(orm);
const [item] = await orm.em.find(OrderItem, { order: order.id }, {
populate: ['product'],
});
expect(item.product.isInitialized()).toBe(true);
expect(mock).toHaveBeenCalledTimes(1);
});

0 comments on commit 07f10c8

Please sign in to comment.