typescriptnestjstypeormmysql2

problem with saving entity that includes another entity


I am new with NestJs and TypeOrm .

my Database is Mysql2 .

This is planOrder.entity

// planOrder.entity
import { Media } from 'src/media/media.entity';
import { Entity,  PrimaryGeneratedColumn, ManyToOne, OneToOne, CreateDateColumn, UpdateDateColumn } from 'typeorm';
import { Plan } from './plan.entity';
import { Transaction } from 'src/transaction/entities/transaction.entity';

@Entity()
export class PlanOrder {
  @PrimaryGeneratedColumn()
  id: number;

  @ManyToOne(() => Media, (media) => media.id)
  media: Media;

  @ManyToOne(() => Plan, (plan) => plan.id)
  plan: Plan

  @OneToOne(() => Transaction, (transaction) => transaction.id)
  transaction: Transaction

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;
}

and when I wanna to create new plan order like this :

// planOrderService.ts

  async create(body: CreatePlanOrderDto, userId: number) {

// creating transaction is done successfully

    const transaction = await this.transactionService.create({
      amount: body.amount,
      description: body.description,
      paymentDate: body.paymentDate,
      refrenceNumber: body.refrenceNumber,
      userId
    })
    const planOrder = this.planOrderRepository.create()

    planOrder.transaction = transaction  // if I remove this line it would be saved without any errors


    try {

// error happens here
      this.planOrderRepository.save(planOrder)

    } catch (error) {
      console.log('e', error)
    }

  }

first I create an transaction .

then I add that transaction to orderPlan entity

then I save it .

but it can't be saved

and I get an error

/home/morteza/Desktop/simple-vedica-back/src/query-builder/UpdateQueryBuilder.ts:681 throw new UpdateValuesMissingError() ^ UpdateValuesMissingError: Cannot perform update query because update values are not defined. Call "qb.set(...)" method to specify updated values. at UpdateQueryBuilder.createUpdateExpression (/home/morteza/Desktop/simple-vedica-back/src/query-builder/UpdateQueryBuilder.ts:681:19) at UpdateQueryBuilder.getQuery (/home/morteza/Desktop/simple-vedica-back/src/query-builder/UpdateQueryBuilder.ts:53:21) at UpdateQueryBuilder.getQueryAndParameters (/home/morteza/Desktop/simple-vedica-back/src/query-builder/QueryBuilder.ts:495:28) at UpdateQueryBuilder.execute (/home/morteza/Desktop/simple-vedica-back/src/query-builder/UpdateQueryBuilder.ts:142:50) at updateSubject (/home/morteza/Desktop/simple-vedica-back/src/persistence/SubjectExecutor.ts:618:63) at Array.map () at SubjectExecutor.executeUpdateOperations (/home/morteza/Desktop/simple-vedica-back/src/persistence/SubjectExecutor.ts:670:34) at SubjectExecutor.execute (/home/morteza/Desktop/simple-vedica-back/src/persistence/SubjectExecutor.ts:148:20) at processTicksAndRejections (node:internal/process/task_queues:95:5) at EntityPersistExecutor.execute (/home/morteza/Desktop/simple-vedica-back/src/persistence/EntityPersistExecutor.ts:182:21)


Solution

  • I believe you need @JoinColumn when using @OneToOne on one of the tables, see here.

    '...We also added @JoinColumn which is required and must be set only on one side of the relation. ...'

    '... @JoinColumn must be set only on one side of the relation - the side that must have the foreign key in the database table. ...'

    so like this

      @OneToOne(() => Transaction, (transaction) => transaction.id)
      @JoinColumn()
      transaction: Transaction
      
    

    See this answer for more details