Skip to content

Commit

Permalink
fix(postgres): respect known schema when loading wild card entity rel…
Browse files Browse the repository at this point in the history
…ations

Closes #2909
  • Loading branch information
B4nan committed Mar 14, 2022
1 parent 042626c commit 61d1e85
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 1 deletion.
7 changes: 6 additions & 1 deletion packages/core/src/entity/EntityLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ export class EntityLoader {
const children = this.getChildReferences<T>(entities, prop, options.refresh);
const meta = this.metadata.find(prop.type)!;
let fk = Utils.getPrimaryKeyHash(meta.primaryKeys);
let schema: string | undefined = options.schema;

if (prop.reference === ReferenceType.ONE_TO_MANY || (prop.reference === ReferenceType.MANY_TO_MANY && !prop.owner)) {
fk = meta.properties[prop.mappedBy].name;
Expand All @@ -246,10 +247,14 @@ export class EntityLoader {
return [];
}

if (!schema && [ReferenceType.ONE_TO_ONE, ReferenceType.MANY_TO_ONE].includes(prop.reference)) {
schema = children.find(e => e.__helper!.__schema)?.__helper!.__schema;
}

const ids = Utils.unique(children.map(e => Utils.getPrimaryKeyValues(e, e.__meta!.primaryKeys, true)));
const where = this.mergePrimaryCondition<T>(ids, fk, options, meta, this.metadata, this.driver.getPlatform());
const fields = this.buildFields(options.fields, prop);
const { refresh, filters, convertCustomTypes, lockMode, strategy, populateWhere, schema } = options;
const { refresh, filters, convertCustomTypes, lockMode, strategy, populateWhere } = options;

return this.em.find(prop.type, where, {
refresh, filters, convertCustomTypes, lockMode, populateWhere,
Expand Down
71 changes: 71 additions & 0 deletions tests/features/multiple-schemas/GH2909.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Entity, ManyToOne, MikroORM, PrimaryKey, Property, wrap } from '@mikro-orm/core';

@Entity({ schema: '*' })
export class Author {

@PrimaryKey()
id!: number;

@Property()
name!: string;

}

@Entity({ schema: '*' })
export class Book {

@PrimaryKey()
id!: number;

@Property()
name!: string;

@ManyToOne({ entity: () => Author, onDelete: 'cascade' })
author!: Author;

}

describe('GH issue 2909', () => {

let orm: MikroORM;

beforeAll(async () => {
orm = await MikroORM.init({
entities: [Author, Book],
dbName: 'mikro_orm_test_2909',
type: 'postgresql',
});

await orm.getSchemaGenerator().refreshDatabase();
await orm.getSchemaGenerator().updateSchema({ schema: 'test' });
await orm.getSchemaGenerator().clearDatabase({ schema: 'test' });
});

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

test('populate already loaded entities', async () => {
const b = new Book();
b.name = 'b';
const author = new Author();
author.name = 'a';
b.author = author;
wrap(b).setSchema('test');
wrap(b.author).setSchema('test');
await orm.em.fork().persistAndFlush(b);
const books = await orm.em.getRepository(Book).findAll({ schema: 'test' });

expect(wrap(books[0]).getSchema()).toBe('test');
expect(wrap(books[0].author).getSchema()).toBe('test');
expect(wrap(books[0].author).isInitialized()).toBe(false);
await orm.em.populate(books, ['author']);

expect(wrap(books[0]).getSchema()).toBe('test');
expect(wrap(books[0].author).getSchema()).toBe('test');
expect(wrap(books[0].author).isInitialized()).toBe(true);
expect(books[0].name).toBe('b');
expect(books[0].author.name).toBe('a');
});

});

0 comments on commit 61d1e85

Please sign in to comment.