TypeORM Cascade insert with oneToMany relationships of auto increment id columns is failing with not-null constraint

Viewed 1308

I am facing an issue while trying to save (insert) an entity with cascade of nested relationships (2 levels)

I have 3 entities Item, ItemCustomization and ItemCustomizationOption (Data model diagram attached below)

enter image description here

When I try to save an Item object like below, its failing to insert a record into ItemCustomizationOption.

The child table entries include a foreign key reference to the auto incremented ID field on the parent table. It seems typeorm is not capturing the auto-increment id from the parent row and supplying it to the child inserts.

{ "name": "Cheese Burger", "itemCustomizations": [ { "title": "Sides", "itemCustomizationOptions": [ { "optionItemId": 1, "price": "3" } ] } ] }

query: INSERT INTO "foodspot"."item_customization_option"("item_id", "price", "customization_id", "option_item_id") VALUES (DEFAULT, $1, $2, $3) -- PARAMETERS: [2,5,4] query failed: INSERT INTO "foodspot"."item_customization_option"("item_id", "price", "customization_id", "option_item_id") VALUES (DEFAULT, $1, $2, $3) -- PARAMETERS: [2,5,4] error: { error: null value in column "item_id" violates not-null constraint

// Item.ts

import {
    Column,
    Entity,
    Index,
    OneToMany,
    PrimaryGeneratedColumn,
  } from 'typeorm';
  import { ItemCustomization } from "./ItemCustomization";
  import { ItemCustomizationOption } from "./ItemCustomizationOption";
  
  @Index("PK_item", ["itemId"], { unique: true })
  @Entity("item", { schema: "foodspot" })
  export class Item {
    @PrimaryGeneratedColumn({ type: "integer", name: "item_id" })
    itemId: number;
  
    @Column("text", { name: "name" })
    name: string;
  
    @Column("money", { name: "price" })
    price: string;
  
    @OneToMany(
      () => ItemCustomization,
      (itemCustomization) => itemCustomization.item, {cascade: ['insert']}
    )
    itemCustomizations: ItemCustomization[];
  
  }
// ItemCustomization.ts

import {
    Column,
    Entity,
    Index,
    JoinColumn,
    ManyToOne,
    OneToMany,
    PrimaryGeneratedColumn,
  } from 'typeorm';
  import { Item } from './Item';
  import { ItemCustomizationOption } from './ItemCustomizationOption';
  
  @Index('PK_item_customization', ['customizationId', 'itemId'], { unique: true })
  @Index('fkIdx_item_customization_item', ['itemId'], {})
  @Entity('item_customization', { schema: 'foodspot' })
  export class ItemCustomization {
    @Column('integer', { primary: true, name: 'item_id' })
    public itemId: number;
  
    @PrimaryGeneratedColumn({ type: 'integer', name: 'customization_id' })
    public customizationId: number;
  
    @Column('text', { name: 'title' })
    public title: string;
  
    @ManyToOne(() => Item, (item) => item.itemCustomizations)
    @JoinColumn([{ name: 'item_id', referencedColumnName: 'itemId' }])
    public item: Item;
  
    @OneToMany(
      () => ItemCustomizationOption,
      (itemCustomizationOption) => itemCustomizationOption.itemCustomization, {cascade: ['insert']}
    )
    public itemCustomizationOptions: ItemCustomizationOption[];
  }
//ItemCustomizationOption.ts

import {
    Column,
    Entity,
    Index,
    JoinColumn,
    ManyToOne,
  } from 'typeorm';
  import { ItemCustomization } from './ItemCustomization';
  import { Item } from './Item';
  
  @Index(
    'PK_item_customization_option',
    ['customizationId', 'itemId', 'optionItemId'],
    { unique: true }
  )
  @Index(
    'fkIdx_item_customization_option_item_customization',
    ['customizationId', 'itemId'],
    {}
  )
  @Index('fkIdx_item_customization_option_option_item', ['optionItemId'], {})
  @Entity('item_customization_option', { schema: 'foodspot' })
  export class ItemCustomizationOption {
    @Column('integer', { primary: true, name: 'item_id' })
    public itemId: number;
  
    @Column('money', { name: 'price' })
    public price: string;
  
    @Column('integer', { primary: true, name: 'customization_id' })
    public customizationId: number;
  
    @Column('integer', { primary: true, name: 'option_item_id' })
    public optionItemId: number;
  
    @ManyToOne(
      () => ItemCustomization,
      (itemCustomization) => itemCustomization.itemCustomizationOptions
    )
    @JoinColumn([
      { name: 'item_id', referencedColumnName: 'itemId' },
      { name: 'customization_id', referencedColumnName: 'customizationId' },
    ])
    public itemCustomization: ItemCustomization;
  
  }
0 Answers
Related