Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v6.0.5 upsert references error (LoadStrategy select in) #5165

Closed
5 tasks done
ladal1 opened this issue Jan 23, 2024 · 10 comments
Closed
5 tasks done

v6.0.5 upsert references error (LoadStrategy select in) #5165

ladal1 opened this issue Jan 23, 2024 · 10 comments

Comments

@ladal1
Copy link

ladal1 commented Jan 23, 2024

Describe the bug

Working with upgrading to v6.0.5 (btw massive thanks for the quick fix for the constructor), I ended up finding an error, with entity using unique index on reference, as shown in reproduction, the upsert and upsert many now fail - with type error

at helper (.../node_modules/@mikro-orm/core/entity/wrap.js:24:19)
at Function.propagateOneToOne (.../node_modules/@mikro-orm/core/entity/EntityHelper.js:191:38)
at Function.propagate (.../node_modules/@mikro-orm/core/entity/EntityHelper.js:181:34)

Reproduction

Just made some entities up (our exact example wouldnt make sense simplified)

@Entity()
@Unique({
  name: 'test_unique_idx',
  properties: ['account', 'nickname'],
})
export class Nickname {
  @ManyToOne(() => Account, {
    nullable: false,
  })
  account: Ref<Account>;

  @Property()
  nicknames: string;
}

@Entity()
export class Account {
  @Property()
  name: string;

  @OneToMany(() => Nickname)
  nicknames: Nickname[];
}

What fails is using reference in upserts:

const account = await em.findOneOrFail(Account, 1);

await em.upsert(
          Nickname,
          {
            account,
            key: "hey",
          },
          {
            onConflictFields: ['account', 'nickname'],
          },
        );

Workaround: using direct id works (object with only field id, does not work and causes knex error, when it tries to insert the whole object into the id column)

// Works as a workaround
await em.upsert(
          Nickname,
          {
            account: account.id,
            key: "hey",
          },
          {
            onConflictFields: ['account', 'nickname'],
          },
        );
// Doesn't (but maybe should as that's how other methods work also)
await em.upsert(
          Nickname,
          {
            account: {
              id: account.id
            },
            key: "hey",
          },
          {
            onConflictFields: ['account', 'nickname'],
          },
        );

Same issue happens with upsertMany

What driver are you using?

@mikro-orm/postgresql

MikroORM version

6.0.5

Node.js version

18

Operating system

mac os

Validations

@B4nan
Copy link
Member

B4nan commented Jan 24, 2024

Looks like I can't reproduce this, I can only see a different error in mongo (Maximum call stack size exceeded caused by Utils.hasNestedKey going in circles).

@ladal1
Copy link
Author

ladal1 commented Jan 24, 2024

Interesting, I'll try to reproduce again and provide different example, but I've isolated it to mikro 6.0.5 previously, I'll try it again today or tomorrow 👍

Edit: didn't find the time, I'll try tomorrow

@ladal1
Copy link
Author

ladal1 commented Jan 25, 2024

I can at least provided a little more stacktrace, interesting issue is that Account is not even the entity we're loading with the findOne. In addition the entity called billingDetail is not supposed to be loaded, it's not in populate fields, nor is it set to be lazy loaded

TypeError: Cannot read properties of undefined (reading '__helper')
    at helper (/Users/.../app/node_modules/@mikro-orm/core/entity/wrap.js:24:19)
    at Function.propagateOneToOne (/Users/.../app/node_modules/@mikro-orm/core/entity/EntityHelper.js:191:38)
    at Function.propagate (/Users/.../app/node_modules/@mikro-orm/core/entity/EntityHelper.js:181:34)
    at Account.set [as billingDetail] (/Users/.../app/node_modules/@mikro-orm/core/entity/EntityHelper.js:160:30)
    at Account.set (/Users/.../app/node_modules/@mikro-orm/core/entity/EntityHelper.js:87:41)
    at _clone (/Users/.../app/node_modules/@mikro-orm/core/utils/clone.js:109:22)
    at _clone (/Users/.../app/node_modules/@mikro-orm/core/utils/clone.js:109:24)
    at _clone (/Users/.../app/node_modules/@mikro-orm/core/utils/clone.js:109:24)
    at _clone (/Users/.../app/node_modules/@mikro-orm/core/utils/clone.js:109:24)
    at _clone (/Users/.../app/node_modules/@mikro-orm/core/utils/clone.js:109:24)

The hierarchy of these entities is:
LoadedEntity (M:1) Account (1:1) Billing Detail
Additionally I can vouch with further testing that this is certainly caused by changes in 6.0.5 as 6.0.4 works fine
So maybe if we added another entity that has 1:1 to the account here it could be replicate? I'll try tommorow, but have been unable to setup mikro orm repo on ARM macbook with the limited time I've had.

@B4nan
Copy link
Member

B4nan commented Jan 26, 2024

on ARM macbook with the limited time I've had.

Weird, I am on M1 for the last two years, it should work fine.

@ladal1
Copy link
Author

ladal1 commented Jan 29, 2024

I've had some docker issues, but it might have been knex since I was previously figuring out and bugfixing issue that was caused by it

@B4nan
Copy link
Member

B4nan commented Jan 29, 2024

nicknames: Nickname[];

Do you actually have this in your entity def? It should be nicknames = new Collection<Nickname>(this).

at Function.propagateOneToOne (/Users/.../app/node_modules/@mikro-orm/core/entity/EntityHelper.js:191:38)

If you have this in your stack trace, your relation needs to be 1:1, not m:1, but then you cannot have an inverse of 1:m kind, that's another suspicious thing.

@ladal1
Copy link
Author

ladal1 commented Jan 30, 2024

I don't that was me just trying to quickly forward you somewhere, I've setup mikro dev env on my machine and I'll let you know if I'm able to replicate it in test (so far I've been unsuccessful, even though it happens every time when running in our app)

EDIT: Ok, I'm able to replicate it in tests, I'll create a minimal example

@ladal1
Copy link
Author

ladal1 commented Jan 30, 2024

https://gist.github.com/ladal1/a357f76e674110d692e09b307477283c

Here is a test which replicates the issue

@B4nan
Copy link
Member

B4nan commented Jan 30, 2024

The third parameter of findOne is an object, not array (since v5, nothing new). If you fix that, it works fine.

@ladal1
Copy link
Author

ladal1 commented Jan 31, 2024

Damn, I was hoping that was the issue, but it was just my oversight during writing the replication when It produced the same error. However you gave me an idea and now I have actually what I whink is causing this - what the replication was missing is the load strategy we're sadly still on, I would have liked to switch to joined (and might do it in response to this), but the issue is apparently cause by combination of the code and select in strategy
loadStrategy: LoadStrategy.SELECT_IN

@ladal1 ladal1 changed the title v6.0.5 upsert references error v6.0.5 upsert references error (LoadStrategy select in) Jan 31, 2024
@B4nan B4nan closed this as completed in 9305653 Feb 2, 2024
B4nan added a commit that referenced this issue Feb 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants