Open tianyingchun opened 5 months ago
Describe the bug
when we use @Transaction() resolver
it will lead QueryRunnerAlreadyReleasedError: Query runner already released. Cannot run queries anymore.
@Resolver() export class ProductRecommendationAdminResolver { constructor( private productRecommendationService: ProductRecommendationService ) {} @Transaction() @Mutation() @Allow(Permission.UpdateCatalog) async updateCrossSellingProducts( @Ctx() ctx: RequestContext, @Args() args: { productId: ID; productIds: [ID] } ): Promise<boolean> { const recommendations: ProductRecommendation[] = await this.productRecommendationService.findAll(ctx, { where: { productId: args.productId, type: RecommendationType.CROSSSELL, }, }); const recommendationsIds = recommendations.map((r) => r.recommendationId); const toDelete = recommendations .filter((r) => !args.productIds.includes(r.recommendationId)) .map((r) => r.id); const toCreate = args.productIds.filter( (r) => !recommendationsIds.includes(r) ); const promises: Promise<any>[] = toCreate.map((id) => this.productRecommendationService.create(ctx, { productId: args.productId, recommendationId: id, type: RecommendationType.CROSSSELL, }) ); if (toDelete.length > 0) { promises.push(this.productRecommendationService.delete(ctx, toDelete)); } await Promise.all(promises); return true; }
//ProductRecommendationService.ts @Injectable() export class ProductRecommendationService { constructor(private connection: TransactionalConnection) {} findAll( ctx: RequestContext, options: FindManyOptions<ProductRecommendation> | undefined ): Promise<ProductRecommendation[]> { return this.connection.getRepository(ctx, ProductRecommendation).find({ relations: ['product'], ...options, }); } findOne( ctx: RequestContext, recommendationId: ID ): Promise<ProductRecommendation | null> { return this.connection.getRepository(ctx, ProductRecommendation).findOne({ where: { recommendationId }, relations: ['product'], }); } async create( ctx: RequestContext, input: ProductRecommendationInput ): Promise<ProductRecommendation> { const product = await this.connection.getRepository(ctx, Product).findOne({ where: { id: input.productId, }, }); const recommendation = await this.connection .getRepository(ctx, Product) .findOne({ where: { id: input.recommendationId, }, }); if (!product || !recommendation) { throw new InternalServerError( 'error.product-recommendation-could-not-be-fetched' ); } const newRecommendation = await this.connection .getRepository(ctx, ProductRecommendation) .save( new ProductRecommendation({ productId: product.id, recommendationId: recommendation.id, type: input.type, }) ); return assertFound(this.findOne(ctx, newRecommendation.id)); } async delete(ctx: RequestContext, ids: ID[]): Promise<DeletionResponse> { try { await this.connection.getRepository(ctx, ProductRecommendation).delete({ id: In(ids), }); return { result: DeletionResult.DELETED, }; } catch (e) { return { result: DeletionResult.NOT_DELETED, message: e instanceof Error ? e.toString() : '', }; } } }
while we exec mutation updateCrossSellingProducts it will give me
mutation
throw new QueryRunnerAlreadyReleasedError_1.QueryRunnerAlreadyReleasedError(); exit process
// product-recommendation.entity.ts @Entity('product_recommendation') export class ProductRecommendation extends VendureEntity { constructor(input?: DeepPartial<ProductRecommendation>) { super(input); } @Index() @Column() productId: ID; @ManyToOne(() => Product, { onDelete: 'CASCADE', nullable: false, }) product: Product; @Index() @Column() recommendationId: ID; @ManyToOne(() => Product, { onDelete: 'CASCADE', nullable: false, }) recommendation: Product; @Column({ type: 'varchar', }) type: RecommendationType; }
extend type Query { productRecommendations(productId: ID!): [ProductRecommendation!]! } extend type Mutation { updateCrossSellingProducts(productId: ID!, productIds: [ID!]!): Boolean! updateUpSellingProducts(productId: ID!, productIds: [ID!]!): Boolean! } extend type Product { recommendations: [ProductRecommendation!]! }
To Reproduce
Expected behavior
Environment (please complete the following information):
Additional context remove @Transaction() decorator from resolver it works fine.
@Transaction()
@tianyingchun did you get the fix, I am having the same issue
Has not been resolved, currently temporarily removing the transaction decorator from the resolver
@tufail what DB are you using?
MySQL
Describe the bug
when we use @Transaction() resolver
it will lead QueryRunnerAlreadyReleasedError: Query runner already released. Cannot run queries anymore.
while we exec
mutation
updateCrossSellingProducts it will give meTo Reproduce
Expected behavior
Environment (please complete the following information):
Additional context remove
@Transaction()
decorator from resolver it works fine.