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

Defining eager: true on customField stops custom entity to load own eager relations #2687

Open
tschortsch opened this issue Feb 20, 2024 · 6 comments
Assignees
Labels
ORM Issues relating to potential bugs in the ORM type: bug 🐛 Something isn't working @vendure/core
Milestone

Comments

@tschortsch
Copy link
Contributor

Describe the bug
I've created a custom entity Cut which looks like the following:

@Entity()
export class Cut extends VendureEntity {
    constructor(input?: DeepPartial<Cut>) {
        super(input);
    }

    @ManyToOne(() => OrderLine, { onDelete: 'CASCADE' })
    orderLine: OrderLine;

    @EntityId()
    orderLineId: ID;

    // code field needs to be loaded eagerly to be able to access its subfields in vendure queries
    @ManyToOne(() => CutCode, { eager: true })
    code: CutCode;

    @EntityId()
    codeId: ID;
}

On the OrderLine I created a customField called cuts which is a ManyToMany relation to the Cut entity above:

config.customFields.OrderLine.push({
    name: 'cuts',
    type: 'relation',
    entity: Cut,
    list: true,
    eager: true,
    label: [
        {
            languageCode: LanguageCode.en,
            value: 'Cuts',
        },
    ],
});

I had to set eager: true because otherwise the addItemToOrder mutation would ignore the customField.cuts when checking if an orderLine already exists for the given productVariant with OrderModifier.getExistingOrderLine() (here: https://github.com/vendure-ecommerce/vendure/blob/master/packages/core/src/service/helpers/order-modifier/order-modifier.ts#L131). This is because the cuts relations is not resolved in the order without loading the relation eagerly.

But as soon as I define this customField to be resolved eagerly all subrelations of this entity (in this case the code field) are not loaded eagerly anymore. I guess this happens because of this logic here: https://github.com/vendure-ecommerce/vendure/blob/master/packages/core/src/api/config/generate-resolvers.ts#L214 which directly returns the translated entity instead of resolving the relation again. It was introduced in this change tianyingchun@3211d75 which fixes the translation of the entity. When I skip the line above locally the code-relation of the Cut entity is resolved eagerly again.

Environment (please complete the following information):

  • @vendure/core version: 2.1.4
  • Nodejs version: 18
  • Database (mysql/postgres etc): postgres
@michaelbromley
Copy link
Member

Hi,

Thanks for the report. Would you be able to create a minimal reproduction I could use to quickly investigate this?

Ideally something like a single-file plugin I can paste into my own config file, plus queries/mutations I can copy-paste that clearly demonstrate the problem.

If you have time to do that it will really help me rapidly find a fix :)

@tschortsch
Copy link
Contributor Author

Sure makes sense. I try to do that as fast as possible. Thanks for your help 👍🏻

@tschortsch
Copy link
Contributor Author

Ok I could create a minimal reproduction plugin. You'll find it here: https://gist.github.com/tschortsch/5e11413dda42f6df0a7106834306c05d#file-eager-relations-bug-plugin-ts. To reproduce the bug you have to do the following:

  1. Setup a vendure instance

  2. The instance needs to have a product variant with the ID: 1 (Or change the hardcoded productVariantId in the plugin to an existing product variant id)

  3. Create a new migration for the custom field and the entities and run it.

  4. Start vendure and execute the following mutation in the shop-api:

    mutation AddCutToOrder {
      addCutToOrder {
        id
        lines {
          id
          customFields {
            cuts {
              id
              name
              code {
                id
                code
              }
            }
          }
        }
      }
    }
    

This will create an Order with an OrderLine and adds a Cut with a related CutCode to this OrderLine. When trying to access the code property in the response it will throw the following error Cannot return null for non-nullable field Cut.code..
As soon as you set the customField.cuts relation to eager: false it will work again.

Hope this helps!

@michaelbromley
Copy link
Member

Thanks for supplying the reproduction gist. Note that I had to change these lines to get the mutation to work to:

        if (!orderLine) {
            const result = await this.orderService.addItemToOrder(ctx, sessionOrder.id, 1, 1);
            if (isGraphQlErrorResult(result)) {
                throw result.message;
            } else {
                orderLine = result.lines[result.lines.length - 1];
            }
        }

This looks like a potential TypeORM bug. What I'm going to do is leave this for now and test it with the upcoming v2.2 in which we have made a major upgrade to TypeORM from v0.3.11 to v0.3.20. If the issue still remains there I'll dive deeper.

@michaelbromley
Copy link
Member

An issue was fixed in v2.2.1 that may resolve this (see commit referenced above)

@tschortsch
Copy link
Contributor Author

Upgraded to v2.2.2 but the eager relation is still not resolved when the customField relation is set to eager: true 😏

@michaelbromley michaelbromley added the ORM Issues relating to potential bugs in the ORM label Jun 17, 2024
@dlhck dlhck added this to the v4.0.0 milestone Sep 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ORM Issues relating to potential bugs in the ORM type: bug 🐛 Something isn't working @vendure/core
Projects
Status: 📅 Planned
Development

No branches or pull requests

3 participants