Search code examples
mikro-orm

How to delete entities from one-to-many collection with only composite primary keys in MariaDB


@Entity()
export class Job {

  @PrimaryKey({ type: BigIntType })
  id: string;

  @OneToMany(() => JobExperienceLevel, 
   jobExperienceLevel => jobExperienceLevel.job, {cascade: Cascade.ALL], orphanRemoval: true})
  experienceLevels = new Collection<JobExperienceLevel>(this);

}


@Entity()
export class JobExperienceLevel {

  @PrimaryKey()
  @Enum({
    items: () => JobExperienceLevelType
  })
  experienceLevel: JobExperienceLevelType;

  @ManyToOne({nullable:false, primary: true, joinColumn: 'job_id'})
  job: Job;
}

export enum JobExperienceLevelType {
  ENTRY_LEVEL = 'ENTRY_LEVEL',
  JUNIOR = 'JUNIOR',
  REGULAR = 'REGULAR',
  SENIOR = 'SENIOR'
}

After calling experienceLevels.removeAll() on some job entity it is generating the following query:

 delete from `job_experience_level` where `experience_level` = 'SENIOR' and `job_id` is null

The database table 'job_experience_level' contains only composite primary keys (experience_level, job_id)

I have checked that before calling removeAll method there is one entity 'SENIOR' in the collection.

I am using entityrepository with persistAndFlush on the job entity.

The problem is that this query is wrong and it should populate the correct job_id.

I also tried to remove the @PrimaryKey() from experienceLevel property, but then there is no delete query in the transaction at all.


Solution

  • As discussed in the comments, there was a bug with orphan removal and composite keys. Upgrade to v3.6.7 to fix it.

    https://github.com/mikro-orm/mikro-orm/blob/master/CHANGELOG.md#367-2020-04-16

    Here is a testcase to make sure it really works:

    https://github.com/mikro-orm/mikro-orm/commit/94c71c89a648e03fad38a93cced7fa92bbfd7ff7#diff-595473b980e4d4384f667f60dbddde2aR1