Search code examples
mongodbmikro-orm

Mikro-ORM still cascades while persisting even when deactivated


I must be doing something wrong with my entity relationships because whenever I try to persist a parent entity with its children, Mikro-ORM keeps trying to persist the children as well, even if cascading has been deactivated for the given properties.

I have some concerts:

import { Entity, PrimaryKey, Property, SerializedPrimaryKey, Collection, ManyToMany } from "@mikro-orm/core";
import { ObjectId } from 'mongodb';
import { Artist } from "./artist";

type Props = {
    readonly _id: ObjectId;
    readonly artists?: Collection<Artist>;
}

@Entity()
export class Concert {
    constructor(private props: Props) { Object.assign(this, props) }

    /* Private variables */
    @PrimaryKey()
    readonly _id!: ObjectId;

    @SerializedPrimaryKey()
    id!: string; // won't be saved in the database

    @ManyToMany({ entity: () => Artist, mappedBy: 'concerts', cascade: [] }) // cascading should be deactivated
    public readonly artists = new Collection<Artist>(this);
}

and some artists :

import { Entity, PrimaryKey, Property, SerializedPrimaryKey, Collection, ManyToMany, Cascade, OneToMany } from "@mikro-orm/core";
import { ObjectId } from 'mongodb';
import { Concert } from "./concert";
import { User } from "./user";

type Props = {
    readonly _id: ObjectId;
    readonly concerts?: Collection<Concert>;
    readonly name: string;
}

@Entity()
export class Artist {
    constructor(private props: Props) { Object.assign(this, props) }

    /* Private variables */
    @PrimaryKey()
    readonly _id!: ObjectId;

    @SerializedPrimaryKey()
    id!: string; // won't be saved in the database

    @ManyToMany({ entity: () => Concert, mappedBy: 'artists', cascade: [], owner: true }) // cascading should be deactivated
    public readonly concerts = new Collection<Concert>(this);

    @Property()
    public readonly name!: string;
}

I already have an artist saved in my mongodb database, under the artist collection with the example ObjectId _id : ObjectId("a").

When trying to persist like so :

const concert = new Concert({ _id: new ObjectId() });

concert.artists.add(new Artist({ "_id": new ObjectId("a"), "name": "" })) 

await concertRepository.persistAndFlush(concert)

I get the following message:

UniqueConstraintViolationException: E11000 duplicate key error collection: db.artist index: _id_ dup key: { _id: ObjectId('a') }

Does anyone know what I'm doing wrong?


Solution

  • So I found where I went wrong, adding the artist like such :

    concert.artists.add(new Artist({ "_id": new ObjectId("a"), "name": "" })) 
    

    just won't cut it. In order to add an existing artist, here is how to proceed :

    // Use the mikro-orm findOne method from the entity manager
    const artist = await artistRepository.findOne(Artist, { _id: new ObjectId('a') })
    // Add it to the collection
    if (artist) concert.artists.add(artist);
    // Now I can persist the concert and the artist is not duplicated
    await concertRepository.persistAndFlush(concert)