help me please. I really don't understand how it's works I have an entity called Product, with a ManyToMany relation with another entity called Car with cascade true flag enabled.
@Entity()
export class Product {
@PrimaryGeneratedColumn()
id: number
@ManyToMany(() => Car, { cascade: true })
@JoinTable()
cars: Car[]
}
The Car entity doesn't contain a reference to the Product entity. That means like i think that the relation is unidirectional. So, when i save a product, i set the cars for this product:
const cars = await this.carService.getByIds(createProductDto.cars)
const newProduct = this.productsRepository.create({
...createProductDto,
cars
})
await this.productsRepository.save(newProduct)
I get the cars entities by ids and save them to the product. This works well. I'm not sure that it is the best way, but i don't know another.
The problems comes when i try to update some existing product in the db. I get the fallowing errors:
ERROR [ExceptionsHandler] duplicate key value violates unique constraint "PK_f7b49d8fd8d09ea2fc2e7542f3f"
or
Error: Cannot query across many-to-many for property cars
or other... Help me please. I want to understand what is the best way to work with such relations. What is the best way to create, update and remove it. Thanks
You claim to have a M:M between Cars and Products, but that is not what you describe. You describe a 1:M for Cars and Products. Referring to Cars in the Products table means a given Car can have many Products, but a given Product can only be used by 1 car. That is the result of referencing Cars from Products (I would not classify as unidirectional as given either one I can get the other, it just the number I can get changes.) However, I believe what you want a M:M. The typical implementation for a M:M requires a 3rd table. With this configuration neither Cars nor Products table references the other, instead the third table references both. Unfortunately, I do not know or recognize your obfuscation manager (ORM you are using). So I'll sketch a possible ddl definition for the tables.
create table cars ( car_id integer generated always as identity primary key
, vin text
, manufacturer text
-- other Car attributes
);
create table products( prod_id integer generated always as identity primary key
, manufacturer text
-- other product
);
-- create the reference/intersection table for M:M Cars:Products
create table car_products( car_id
, prod_id
-- attributes that pertain only to the combination of
-- of the other tables
, model_code text
, serial_number text
-- constraints
, constraint car_products_pk
primary key (car_id, prod_id)
, constraint car_products_2_cars_fk
foreign key (car_id)
references cars(car_id)
on delete cascade
, constatint car_products_2_products_fk
foreign key(prod_id)
references products(prod_id)
on delete cascade
);
Now with this setup a given Car can have any number of Products and a given product can be user by any number of cars. (Note: In this set up a Product is differently from a part.) I hope this helps you understand 1:M relationships vs M:M relationships.