Description:
I'm encountering issues when trying to extend the Product entity from @medusajs/medusa and establish a one-to-one relationship with a custom entity, ProductSpecification. The problem appears to be due to conflicts or missing configurations in the base Product entity when using TypeORM decorators. This issue arose after installing the custom-attributes node module; the relationship was working correctly before this installation. The error occurs specifically when I click on the product details in the admin UI.
Steps to Reproduce:
Create a custom entity ProductSpecification with a one-to-one relationship to the Product entity.
Extend the Product entity from @medusajs/medusa.
Define the relationship in the extended Product entity.
Install the custom-attributes node module.
Click on the product details in the admin UI.
Code Examples:
Product Entity (models/product.ts):
import { Entity, OneToOne } from "typeorm";
import { Product as MedusaProduct } from "@medusajs/medusa";
import { ProductSpecification } from "./product-specification";
@entity()
export class Product extends MedusaProduct {
@OnetoOne(() => ProductSpecification, (specification) => specification.product)
specification?: ProductSpecification | null;
}
ProductSpecification Entity (models/product-specification.ts):
import {
BeforeInsert,
Column,
Entity,
OneToOne,
JoinColumn
} from "typeorm";
import { SoftDeletableEntity } from "@medusajs/medusa";
import { generateEntityId } from "@medusajs/medusa/dist/utils";
import { Product } from "./product";
@entity()
export class ProductSpecification extends SoftDeletableEntity {
@column({ type: "varchar" })
model: string | null;
@column({ type: "varchar" })
product_id: string;
@OnetoOne(() => Product, (product) => product.specification)
@joincolumn({ name: "product_id", referencedColumnName: "id" })
product?: Product | null;
@BeforeInsert()
private beforeInsert(): void {
this.id = generateEntityId(this.id, "prod_spec");
}
}
Configuration for Extending Product Fields (extend-product-fields.ts):
export default async function () {
const imports = (await import(
"@medusajs/medusa/dist/api/routes/store/products/index"
)) as any;
imports.defaultStoreProductsRelations = [
...imports.defaultStoreProductsRelations,
"specification",
];
imports.allowedStoreProductsRelations = [
...imports.allowedStoreProductsRelations,
"specification",
];
const admin_imports = (await import(
"@medusajs/medusa/dist/api/routes/admin/products/index"
)) as any;
admin_imports.defaultAdminProductRelations = [
...admin_imports.defaultAdminProductRelations,
"specification",
];
admin_imports.defaultAdminGetProductsVariantsRelations = [
...admin_imports.defaultAdminGetProductsVariantsRelations,
"specification",
];
admin_imports.defaultAdminProductRemoteQueryObject = [
...admin_imports.defaultAdminProductRemoteQueryObject,
"specification",
];
}
Expected Behavior:
The Product entity should be able to define a relationship with the ProductSpecification entity without issues. Additionally, the relationship should be recognized and managed by TypeORM.
Actual Behavior:
Adding a @OnetoOne decorator to the extended Product entity results in the following error when clicking on the product details in the admin UI:
error: Relation with property path specification in entity was not found.
TypeORMError: Relation with property path specification in entity was not found.
at JoinAttribute.getValue (/path/to/project/node_modules/typeorm/query-builder/JoinAttribute.js:109:23)
at get relation [as relation] (/path/to/project/node_modules/typeorm/query-builder/JoinAttribute.js:111:53)
at get metadata [as metadata] (/path/to/project/node_modules/typeorm/query-builder/JoinAttribute.js:122:18)
at SelectQueryBuilder.join (/path/to/project/node_modules/typeorm/query-builder/SelectQueryBuilder.js:963:53)
at SelectQueryBuilder.leftJoin (/path/to/project/node_modules/typeorm/query-builder/SelectQueryBuilder.js:195:14)
at SelectQueryBuilder.leftJoinAndSelect (/path/to/project/node_modules/typeorm/query-builder/SelectQueryBuilder.js:215:14)
at /path/to/project/node_modules/@medusajs/medusa/dist/utils/repository.js:148:80
at step (/path/to/project/node_modules/@medusajs/medusa/dist/utils/repository.js:33:23)
at Object.next (/path/to/project/node_modules/@medusajs/medusa/dist/utils/repository.js:14:53)
at /path/to/project/node_modules/@medusajs/medusa/dist/utils/repository.js:8:71