0

在 GraphQL 中,在创建突变以创建作业或更新作业时,我收到以下错误:

Error: Error caused by mis-matched default values for the "id" field of "BaseEntity". The default value from the decorator "null" is not equal to the property initializer value "d548e85d-1c38-47e1-9e80-a98532204b97". Ensure that these values match.

对同一实体的查询不会出现该错误。我的工作实体如下所示:

export enum JobStatusType {
  NEW,
  STARTED,
  FINISHED,
  CANCELLED,
}
registerEnumType(JobStatusType, {
  name: 'JobStatusType',
  description: 'The State of the job.',
});

export enum JobType {
  EMERGENCY,
  SHORT_NOTICE,
  REGULAR,
}
registerEnumType(JobType, {
  name: 'JobType',
  description: 'The category/type of the job.',
});

@ObjectType({
  description:
    'Job Entity. This represents any kind of job that is being offered by AGENCY Organization, and potentially fulfilled by a user from a COURIER Organization.',
})
@InputType({ isAbstract: true })
@Entity()
export class Job extends BaseEntity {
  @ManyToOne({
    entity: () => Location,
    cascade: [Cascade.REMOVE, Cascade.PERSIST],
    strategy: LoadStrategy.JOINED,
    nullable: false,
  })
  @Field((_type) => Location, { nullable: false })
  public pickupCity: Location;

  @ManyToOne({
    entity: () => Location,
    cascade: [Cascade.REMOVE, Cascade.PERSIST],
    strategy: LoadStrategy.JOINED,
    nullable: false,
  })
  @Field((_type) => Location, { nullable: false })
  public dropoffCity: Location;

  @Property({
    nullable: false,
    comment: 'Pickup Date and Time',
  }) // necessary for MikroORM entity
  @Field((__type) => Date, {
    description: 'Pickup Date and Time',
    nullable: false,
  }) // necessary for NestJS/Graphql
  public pickupTime: Date;

  @Property({
    nullable: false,
    comment: 'Return to source Date and Time',
  }) // necessary for MikroORM entity
  @Field((__type) => Date, {
    description: 'Return to source Date and Time',
    nullable: false,
  }) // necessary for NestJS/Graphql
  public returnTime: Date;

  @Property({ type: 'text', nullable: false })
  @Field({
    description: 'The description of the Items',
    nullable: false,
  })
  public itemsDescription: string;

  @Property({ length: 150, nullable: true })
  @Field({ description: 'Title of the Job', nullable: true })
  public title?: string;

  @Property({ type: 'text', nullable: true })
  @Field({
    description: 'The description of the Job.',
    nullable: true,
  })
  public description?: string;

  @Property({ nullable: true }) // necessary for MikroORM entity
  @Field((_type) => Boolean, {
    description: 'has an incident occured',
    nullable: true,
  }) // necessary for NestJS/Graphql
  public hasIncident?: boolean;

  @Property({ type: 'number', nullable: true })
  @Field({
    description: 'The daily rate for the job as proposed by Agency.',
    nullable: true,
  })
  public dailyRate?: number;

  @Property({ type: 'number', nullable: true })
  @Field({
    description: 'The fixed rate for the job as proposed by Agency.',
    nullable: true,
  })
  public fixedRate?: number;

  @Property({ type: 'number', nullable: true })
  @Field({
    description: 'The kickoff fee for the job as proposed by Agency.',
    nullable: true,
  })
  public kickOffFee?: number;

  @Property({ type: 'number', nullable: true })
  @Field({
    description: 'The transportation fee for the job as proposed by Agency.',
    nullable: true,
  })
  public transportationFee?: number;

  @Enum({
    items: () => Currency,
    nullable: true,
    type: Enum,
  })
  @Field((_type) => Currency, {
    description: 'Currency for the job as proposed by Agency.',
    nullable: true,
  })
  public clientAgencycurrency?: Currency;

  @Property({ nullable: true }) // necessary for MikroORM entity
  @Field((_type) => Boolean, {
    description: 'is the accomodation booked by courier as proposed by Agency.',
    nullable: true,
  }) // necessary for NestJS/Graphql
  public isAccomodationBookedByCourier?: boolean;

  @Property({ nullable: true }) // necessary for MikroORM entity
  @Field((_type) => Boolean, {
    description: 'is the accomodation paid by courier as proposed by Agency.',
    nullable: true,
  }) // necessary for NestJS/Graphql
  public isAccomodationPaidByCourier?: boolean;

  @Property({ type: 'number', nullable: true })
  @Field({
    description: 'The number of items transported in the job',
    nullable: true,
  })
  public numOfItems?: number;

  @Property({ type: 'number', nullable: true })
  @Field({
    description: 'The total weights of items transported in the job',
    nullable: true,
  })
  public weightfItems?: number;

  @Property({ type: 'number', nullable: true })
  @Field({
    description: 'The number of couriers required to do the job',
    nullable: true,
  })
  public numOfCouriersRequired?: number;

  @ManyToOne({
    entity: () => Location,
    cascade: [Cascade.REMOVE, Cascade.PERSIST],
    strategy: LoadStrategy.JOINED,
    nullable: true,
  })
  @Field((_type) => Location, { nullable: true })
  public pickupAddress?: Location;

  @Property({ type: 'text', nullable: true })
  @Field({
    description: 'Pickup Address Description',
    nullable: true,
  })
  public pickupAddressDescription?: string;

  @ManyToOne({
    entity: () => Location,
    cascade: [Cascade.REMOVE, Cascade.PERSIST],
    strategy: LoadStrategy.JOINED,
    nullable: true,
  })
  @Field((_type) => Location, { nullable: true })
  public startAirport?: Location;

  @ManyToOne({
    entity: () => Location,
    cascade: [Cascade.REMOVE, Cascade.PERSIST],
    strategy: LoadStrategy.JOINED,
    nullable: true,
  })
  @Field((_type) => Location, { nullable: true })
  public dropoffAddress?: Location;

  @Property({ type: 'text', nullable: true })
  @Field({
    description: 'Dropoff Address Description',
    nullable: true,
  })
  public dropoffAddressDescription?: string;

  @ManyToOne({
    entity: () => Location,
    cascade: [Cascade.REMOVE, Cascade.PERSIST],
    strategy: LoadStrategy.JOINED,
    nullable: true,
  })
  @Field((_type) => Location, { nullable: true })
  public endAirport?: Location;

  @Property({
    nullable: true,
    comment: 'Dropoff Date and Time',
  }) // necessary for MikroORM entity
  @Field((__type) => Date, {
    description: 'Dropoff Date and Time',
    nullable: true,
  }) // necessary for NestJS/Graphql
  public dropoffTime?: Date;

  @Property({ type: 'text', nullable: true })
  @Field({
    description: 'Specific Instructions or Details',
    nullable: true,
  })
  public jobDetails?: string;

  @Property({ nullable: true }) // necessary for MikroORM entity
  @Field((_type) => Boolean, {
    description: 'is car required for the job',
    nullable: true,
  }) // necessary for NestJS/Graphql
  public isCarRequiredForJob?: boolean;

  @Property({ nullable: true }) // necessary for MikroORM entity
  @Field((_type) => Boolean, {
    description: 'is driving license required for the job',
    nullable: true,
  }) // necessary for NestJS/Graphql
  public isDrivingLicenseRequiredForJob?: boolean;

  @Enum({
    items: () => JobStatusType,
    nullable: false,
    type: Enum,
    default: JobStatusType.NEW,
  })
  @Field((_type) => JobStatusType, {
    description: 'Job Status Type (new, started, finished, cancelled)',
    defaultValue: JobStatusType.NEW,
    nullable: false,
  })
  public jobType?: JobType;

  @Enum({
    items: () => JobStatusType,
    nullable: false,
    type: Enum,
  })
  @Field((_type) => JobStatusType, {
    description: 'Job Status Type (new, started, finished, cancelled)',
    nullable: false,
  })
  public jobStatusType?: JobStatusType;

  @OneToMany({
    entity: () => JobAgencyCourierOrganization,
    mappedBy: (organizationJob) => organizationJob.job,
    orphanRemoval: true,
    cascade: [Cascade.PERSIST, Cascade.REMOVE],
    strategy: LoadStrategy.JOINED,
  })
  @Field((_type) => [JobAgencyCourierOrganization], { nullable: true })
  public jobAgencyCourierOrganizations?: Collection<JobAgencyCourierOrganization> =
    new Collection<JobAgencyCourierOrganization>(this);

  @OneToMany({
    entity: () => JobClientAgencyOrganization,
    mappedBy: (organizationJob) => organizationJob.job,
    orphanRemoval: true,
    cascade: [Cascade.PERSIST, Cascade.REMOVE],
    strategy: LoadStrategy.JOINED,
  })
  @Field((_type) => [JobClientAgencyOrganization], { nullable: true })
  public jobClientAgencyOrganizations?: Collection<JobClientAgencyOrganization> =
    new Collection<JobClientAgencyOrganization>(this);

  constructor(attributes: {
    id?: string;
    pickupCity: Location;
    dropoffCity: Location;
    pickupTime: Date;
    returnTime: Date;
    itemsDescription: string;
    clientAgencycurrency?: Currency;
    dailyRate?: number;
    description?: string;
    dropoffAddress?: Location;
    dropoffAddressDescription?: string;
    dropoffTime?: Date;
    endAirport?: Location;
    fixedRate?: number;
    hasIncident?: boolean;
    isAccomodationBookedByCourier?: boolean;
    isAccomodationPaidByCourier?: boolean;
    isCarRequiredForJob?: boolean;
    isDrivingLicenseRequiredForJob?: boolean;
    jobStatusType?: JobStatusType;
    jobType?: JobType;
    kickOffFee?: number;
    numOfCouriersRequired?: number;
    numOfItems?: number;
    pickupAddress?: Location;
    pickupAddressDescription?: string;
    startAirport?: Location;
    title?: string;
    transportationFee?: number;
    weightfItems?: number;
  }) {
    super(attributes?.id);
    if (attributes) {
      Object.assign(this, attributes);
    }
  }
}

被引用的 BaseEntity 如下所示:

@ObjectType({ isAbstract: true }) // GraphQL
@InputType({ isAbstract: true }) // GraphQL
@Entity({ abstract: true }) // GraphQL
@Directive('@extends') // GraphQL
@Directive('@key(fields: "id")') // GraphQL
@Filter({
  name: 'notDeleted',
  cond: { deletedAt: { $eq: null } },
  default: true,
}) // This filter (not soft-deleted) is active by default.
@Filter({
  name: 'all',
  cond: {
    $or: [{ deletedAt: { $ne: null } }, { deletedAt: { $eq: null } }],
  },
}) // This filter returns all rows (deleted and not deleted).
@Filter({ name: 'deleted', cond: { deletedAt: { $ne: null } } })
export abstract class BaseEntity {
  @Field((_type) => ID, { nullable: false, defaultValue: null }) // GraphQL
  @PrimaryKey({ type: 'uuid', nullable: false }) // NestJs / MikroORM
  public id: string;

  @Field((_type) => Date)
  @Property({ type: Date, nullable: false })
  public createdAt: Date = new Date();

  @Field((_type) => Date)
  @Property({ onUpdate: () => new Date(), type: Date, nullable: false })
  public updatedAt: Date = new Date();

  @Property({ default: null, nullable: true })
  @Field((_type) => Date, {
    description:
      'This is not null if the entity is marked as deleted (soft delete).',
    nullable: true,
  })
  public deletedAt?: Date;

  constructor(id?: string) {
    this.id = id || v4();
  }
}

Job 的 InputType,JobInput 定义如下:

@InputType()
export class JobInput extends PickType(
  Job,
  [
    'clientAgencycurrency',
    'dailyRate',
    'dropoffAddress',
    'dropoffAddressDescription',
    'dropoffCity',
    'dropoffTime',
    'endAirport',
    'fixedRate',
    'hasIncident',
    'isAccomodationBookedByCourier',
    'isAccomodationPaidByCourier',
    'isCarRequiredForJob',
    'isDrivingLicenseRequiredForJob',
    'itemsDescription',
    'kickOffFee',
    'numOfCouriersRequired',
    'numOfItems',
    'pickupAddress',
    'pickupAddressDescription',
    'pickupCity',
    'pickupTime',
    'returnTime',
    'startAirport',
    'transportationFee',
    'weightfItems',
  ],
  InputType,
) {
  // This needs to be overridden and cannot be obtained from the base.entity.ts via PickType, as this would result in a default value upon initialization.
  @Field((_type) => ID, { nullable: false })
  public id: string;
}

这是我的突变:

 @Mutation((_returns) => Job)
  async createJob(
    @Info() info,
    @CurrentUserContextGql() userContext: UserContext,
    @Args('jobInput', {
      nullable: false,
      type: () => JobInput,
    })
    jobInput: JobInput,
  ): Promise<Job> {
    // TODO: check for allowed to create first!
    const job = await this.jobService.create(userContext, jobInput);
    return job;
  }

对于其他实体和输入类型,我没有收到此错误。我应该怎么办?

4

0 回答 0