Describe the bug
Hey there! First of all, thanks a lot for this very stable and intuitive TS ORM! ❤️
Since a couple of versions, an @Embeddable can have a @ManyToOne relationship through its parent. This works fine.
However, the inverse side that would use a @OneToMany collection cannot populate the user.
Stack trace
No stack trace since no error.
To Reproduce
Here is an example setup:
@Embeddable()
export class Address {
constructor(street: string, city: string, country: Country) {
this.street = street
this.city = city
this.country = country
}
@Property()
street!: string
@Property()
city!: string
@ManyToOne()
country!: Country
}
@Entity()
export class Country {
@PrimaryKey({ autoincrement: true })
id!: number
@Property()
name!: string
@OneToMany(() => User, (user) => (user as any).address_country)
users = new Collection<User>(this)
}
@Entity()
export class User {
@PrimaryKey({ autoincrement: true })
id!: number
@Property()
name!: string
@Embedded(() => Address)
address!: Address
}
You can populate the country property from the side of the User, but you cannot populate the users collection from the Country's side.
Expected behavior
One should be able to populate the users collection also from the Country's side.
Additional context
Here is a test suite that explains everything in detail:
import { MikroORM } from '@mikro-orm/core'
import { SqliteDriver } from '@mikro-orm/sqlite'
import { Address } from './address'
import { Country } from './country'
import { User } from './user'
describe('Issue', () => {
let orm: MikroORM
beforeAll(async () => {
orm = await MikroORM.init({
entities: [User, Country, Address],
dbName: ':memory:',
driver: SqliteDriver,
allowGlobalContext: true,
})
await orm.schema.createSchema()
})
afterEach(async () => {
await orm.schema.clearDatabase()
})
afterAll(() => orm.close(true))
beforeEach(async () => {
const germany = orm.em.create(Country, { name: 'Germany' })
orm.em.create(User, { name: 'John Doe', address: new Address('Main Street', 'Berlin', germany) })
await orm.em.flush()
})
test('the country can be populated through the address of a user', async () => {
const user = await orm.em.findOneOrFail(User, { name: 'John Doe' }, { populate: ['address.country'] })
expect(user.address.country.name).toBe('Germany')
})
test('the users can be populated through the address of a country', async () => {
const country = await orm.em.findOneOrFail(Country, { name: 'Germany' }, { populate: ['users'] })
expect(country.users[0].name).toBe('John Doe') // ❌ this one fails
})
test('can init the user collection of a country', async () => {
const country = await orm.em.findOneOrFail(Country, { name: 'Germany' })
await country.users.init()
expect(country.users.isInitialized()).toBe(true)
expect(country.users[0].name).toBe('John Doe')
})
})
Versions
| Dependency |
Version |
| node |
16.15.1 |
| typescript |
4.9.5 |
| mikro-orm |
5.6.13 |
| sqlite3 |
5.1.4 |
Describe the bug
Hey there! First of all, thanks a lot for this very stable and intuitive TS ORM! ❤️
Since a couple of versions, an
@Embeddablecan have a@ManyToOnerelationship through its parent. This works fine.However, the inverse side that would use a
@OneToManycollection cannot populate the user.Stack trace
To Reproduce
Here is an example setup:
You can populate the
countryproperty from the side of theUser, but you cannot populate theuserscollection from theCountry's side.Expected behavior
One should be able to populate the
userscollection also from theCountry's side.Additional context
Here is a test suite that explains everything in detail:
Versions