Typeorm issue: Foreign key insertion not functioning correctly with cascade enabled

I currently have a situation where I am dealing with 2 entities that have a ManyToOne/OneToMany Relation with cascade enabled.

< One: Sender ---- Many: Transfer (cascade insert) >

My goal is to add 2 new Transfer instances with the same sender. However, I am encountering an issue where the uniqueness constraint of the sender address is violated during the second insert.

@Entity()
export class Transfer extends BaseEntity {
  // Each transfer has an id and the sender
  @PrimaryGeneratedColumn()
  id!: number;

  @ManyToOne(() => Sender, (sender) => sender.sends, { 
      nullable: false, 
      eager: true, 
      cascade: ["insert"] })
  sender!: Sender
}

@Entity()
export class Sender extends BaseEntity {
  // Each address has an id and a value of the address
  @PrimaryGeneratedColumn()
  id!: number;

  @Column({ unique: true, nullable: false })
  address!: string;

  @OneToMany(() => Transfer, (transfer) => transfer.sender, { 
      eager: false, 
      cascade: false })
  sends!: Transfer[]
}
// get typeorm EntityManager
const em = dataSource.manager

const a = 'test_address'

// save the first transfer - cascade will also insert the sender
await em.save(Transfer, { sender: { address: a}})

// save a new transfer by the same sender
const s = await em.findOneBy(Sender, { address: a })
await em.save(Transfer, { sender: s })

Is there a way for me to add a new transfer without triggering the insertion of a new sender if the sender already exists?

Answer №1

Here are some key points to consider:

  1. Make sure to only set eager: true on one side of the relationship.

  2. The issue arises when the sender is not the primary key. How can TypeOrm correctly identify the sender without a unique identifier? This confusion leads to a new entry being created, erroneously labeled as a "duplicate." To resolve this, I suggest using the unique value, such as the sender, as the primary key.

  3. In this context, cascade insert means that if a new Sender instance is assigned to this relation, it will be automatically added to the database when you save this transfer entity.

    @ManyToOne(() => Sender, (sender) => sender.sends, { 
          nullable: false, 
          eager: true, 
          cascade: ["insert"] })
      sender!: Sender
  1. Consider implementing the following:
 @OneToMany(() => Transfer, (transfer) => transfer.sender)
      sends!: Transfer[]

Answer №2

It appears that the issue arises when the second Transfer is created, causing TypeORM to attempt inserting a new Sender with the same address as an existing sender, leading to a conflict with the unique string constraint set on Sender.address:

  @Column({ unique: true, nullable: false })
  address!: string;

In this case, TypeORM's insertion process does not verify if the object already exists; rather, it is the unique flag on Sender.address that enforces uniqueness.

Utilizing TypeORM Upsert could potentially address the object existence check issue when performing inserts. However, incorporating it into the existing cascade insert setup with cascade: ["insert"] may not be straightforward, as outlined in the documentation:

cascade: boolean | ("insert" | "update")[] - If set to true, the related object will be inserted and updated in the database. You can also specify an array of cascade options.

An ongoing concern is the lack of support for cascade inserts in TypeOrm, as highlighted in an open issue on their GitHub page (illustrated with the User / Color entities scenario, where Color is uniquely identified by a string similar to Sender.address): https://github.com/typeorm/typeorm/issues/7171

To navigate this situation, two potential solutions are proposed:

  1. Removing cascade: ["insert"] from the Sender.entity and implementing additional logic within Transfer.save to manage sender creation if it does not already exist. Subscribers could be leveraged to monitor Transfer insertions within the entity and execute the necessary sender insertion logic: https://github.com/typeorm/typeorm/blob/master/docs/listeners-and-subscribers.md -
  2. Engaging with the TypeORM community on GitHub (referencing the aforementioned issue link) to explore alternative workarounds or solutions.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Dealing with the "this" problem in TypeScript and its impact on scope

Here is my code snippet: class MyClass { name = "MyClass"; // traditional method definition getName1(){ return this.name; } // method defined as an arrow function getName2 = () => { return this.name; ...

Utilizing Google Closure Library with Angular 6

I am looking to integrate the google closure library into my angular 6 application. To achieve this, I have utilized the following commands: npm install google-closure-compiler and npm install google-closure-library. My application can be successfully co ...

Is there a way to integrate the AuthState TypeScript Interface into the react-oidc-context Node package for testing in Next.js?

We are currently working on a Next.js application that utilizes the react-oidc-context Node module for authentication with ADFS. During our testing phase using Vitest, we encountered the following error: TypeError: Cannot read properties of undefined (rea ...

Dynamically altering the CSS4 variables in real time

I am facing the challenge of managing multiple CSS4 variables, including primary, for various companies. How can I dynamically change the primary CSS4 variable color based on the company? Note: My specific requirement is to update the primary variable glo ...

Encountering an ECONNREFUSED error upon upgrading from Next.js 12 to 13

After upgrading from Nextjs 12 to 13, I am experiencing issues where every time I try to run the application, I encounter ECONNREFUSED to my local host but the port seems to keep changing. This results in the application not rendering properly. > <a ...

Utilizing React with Typescript to access specific props

I am a newcomer to React and TypeScript and I am facing a challenge while trying to enhance an existing component by creating a wrapper around it. The issue I am encountering is related to adding my custom values to the properties. My goal is to extend th ...

Encountering a 405 HTTP error in Angular8 app when refreshing the page

Currently, I am working on a project using Angular8 and .NET Core 3.0 in Visual Studio. Everything is running smoothly except for one issue that arises when I press F5 on a page with a form. The error message that pops up reads: Failed to load resource: ...

Angular firing a function in the then clause before the initial function is executed

I have a situation where I need to make multiple service calls simultaneously, but there is one call that must be completed before the others are triggered. I have set it up so that the other calls should only happen after the .then(function() {}) block of ...

The process of ensuring a component is able to watch for the router even when it is not within the router

I am facing an issue with setting v-if for an element to get a boolean value from a function when the router changes the URL. Here is the code snippet for my Header component: <template> <header class="wfm-header"> <div class=" ...

What's the best way to implement asynchronous state updating in React and Redux?

In my React incremental-style game, I have a setInterval function set up in App.ts: useEffect(() => { const loop = setInterval(() => { if (runStatus) { setTime(time + 1); } }, rate); return () => clearInterval(lo ...

What is the method to define a function that strictly accepts a value of type T only if IsSomething<T> evaluates to true?

In my system, there is a complex generic type called IsUnique<T> that evaluates to either true or false based on the input type T: type IsUnique<T> = (/* ... */) ? true : false; Now I am looking to develop a function that takes an unique value ...

I can't decide which one to choose, "ngx-bootstrap" or "@ng-bootstrap/ng-bootstrap."

Currently, I am in the process of deciding whether to use Bootstrap 4 with angular 4 for my upcoming project. However, I find myself torn between choosing npm install --save @ng-bootstrap/ng-bootstrap or npm install ngx-bootstrap --save. Could someone pl ...

Deactivate the FormGroup by implementing Validators

In my form, I have a checkbox group named formArray within my checkboxForm. The task at hand is to disable the submit button if none of the checkboxes are checked. To achieve this, I created a custom validator for my checkboxForm and here is my approach: ...

Identifying the various types in Typescript

In the process of developing a solution for Excel involving data from an Office API, I encountered the challenge of distinguishing between different types that a function can return. Specifically, the data retrieved as a string may belong to either a "Cell ...

Tips for accessing the PR number in a Node.js GitHub Probot listening for the `pull_request` event

I've recently developed a GitHub probot application using nodejs and typescript. Currently, I have set up an event listener for the pull_request event. How can I extract the pr_number from the context object within the probot? The snippet below is fr ...

Limitations on quantity utilizing typescript

Looking to create a type/interface with generics that has two properties: interface Response<T> { status: number; data: T | undefined; } Specifically, I want to enforce a rule where if the status is not equal to 200, then data must be undefined. ...

The function Observable.timer in Angular rxjs is throwing an error when imported

Encountering an error in my Angular application that reads: ERROR TypeError: rxjs_Observable__WEBPACK_IMPORTED_MODULE_4__.Observable.timer is not a function at SwitchMapSubscriber.project (hybrid.effect.ts:20) at SwitchMapSubscriber.push ...

What steps should I take to fix this TypeScript error?

I've been struggling to fix this error, but I'm unsure of the best way to resolve it. Here is the code snippet I've been working with:https://i.sstatic.net/m6M48.png Here is the specific error message: https://i.sstatic.net/uk6QY.png ...

What is the process for integrating the node-menu package into my project without utilizing the require statement?

Is there a way to incorporate node-menu into my TypeScript project without using require, like this: const menu = require('node-menu'); Whenever I attempt to import node-menu into my project, I encounter the following errors: https://i.sstatic. ...

What is the best way to identify a particular subtype of HTMLElement based on its tag name and then save that element within another one?

I have a function that generates a node and returns it. Here is an example implementation: addElement: function ({ parentNode, elementName, tagName, }) { // Creates and appends the new node. parentNode[elementName] = document.createEl ...