Search code examples
node.jstypescripttypeorm

TypeORM: duplicate key while saving relationships with existing entities


I have the following entity in TypeORM:

@Entity('category')
export class Category {

  @Column({ length: 80 })
  public name: string;

  @OneToOne(
    (): ObjectType<Category> => Category,
    (category: Category): Category => category.parent,
    {
      cascade: ['insert', 'update'],
    }
  )
  @JoinColumn({ name: 'parent', referencedColumnName: 'id' })
  public parent: Category;
}

Next, I save some categories in my database:

let parentCategory = new Category();
parentCategory.name = 'Parent Category';

let childCategory = new Category();
childCategory.name = 'Child Category';
childCategory.parent = parentCategory;

connection.manager.save(childCategory);

Finally, I want to add a new child category of "Parent Category" (consider the parent category was loaded from the database and contains its ID):

let newChildCategory = new Category();
newChildCategory.name = 'New Child Category';
newChildCategory.parent = childCategory.parent; //<- childCategory.parent contains the parent ID

connection.manager.save(newChildCategory); //<- Throws duplicate key error due to cascade

One viable solution is defining the ON DUPLICATE KEY behaviour, which must be implemented manually according to this information. Is there another solution to do it while saving the entity without having to write the whole query as in my example?

This GitHub repository contains an application replicating the issue.


Solution

  • Can you try

    @ManyToOne(
        type => Category,
        category => category.children,
        {
          cascade: ['insert', 'update'],
        }
    )
    public parent: Category;
    
    @OneToMany(
        type => Category,
        category => category.parent,
        {
          cascade: ['insert', 'update'],
        }
    )
    public children: Category[];
    

    ?

    I'm not sure it's the root cause of your problem, but parent's type should be Category and not category. It's strange that you IDE didn't warn you btw.

    Watch out, though, because you defined your category-parent relation to be of OneToOne type, but from the example you provided you're using it as a OneToMany/ManyToOne relation!