I've been utilizing TypeORM to develop a task system that involves various entities such as owning committee, related committees, project leads, and employee entries.
My expectation is to pass a unit test successfully with the following code execution:
const taskDetails: TaskDetails = {
title: "Baz Creation",
startDate: new Date(),
endDate: new Date(),
committeeId: newCommittee1.committeeId,
};
const taskPayload1 = {
committees: [newCommittee1, newCommittee2],
projectLead: newUser1,
membersToAdd: [newUser1, newUser2, newUser3],
};
await taskDAO.createTask(newCommittee1, taskDetails, taskPayload1.committees, taskPayload1.projectLead, taskPayload1.membersToAdd);
However, an error is being thrown, stating:
QueryFailedError: null value in column "memberUserId" of relation "tasks_for_member" violates not-null constraint
at PostgresQueryRunner.query (src/driver/postgres/PostgresQueryRunner.ts:299:19)
at InsertQueryBuilder.execute (src/query-builder/InsertQueryBuilder.ts:163:33)
at SubjectExecutor.executeInsertOperations (src/persistence/SubjectExecutor.ts:428:42)
at SubjectExecutor.execute (src/persistence/SubjectExecutor.ts:137:9)
at EntityPersistExecutor.execute (src/persistence/EntityPersistExecutor.ts:197:21)
at TaskDAO.createTask (src/db/dao/task.dao.ts:49:13)
at Object.<anonymous> (tests/dbUtil/purgeDb.test.ts:132:9)
The error message suggests that there should be an entry in the join table, but it seems like I am unable to make TypeORM create that entry correctly.
I'm confused because:
(a) TypeORM should handle creating entries in the join table automatically. (b) All relations in my database are set to be nullable. See below for details.
Below are snippets from my Task and Member entity files:
Task.ts
@Entity()
export class Task {
@PrimaryGeneratedColumn()
taskId: number;
@Column({ nullable: true })
description: string;
@Column({ nullable: true })
status: Role;
@ManyToMany(() => Member, (member: Member) => member.tasks, { nullable: true, onDelete: "CASCADE" })
@JoinTable({ name: "task_leads" })
leads?: Member[];
@ManyToMany(() => Member, (member: Member) => member.tasks, { nullable: true, onDelete: "CASCADE" })
@JoinTable({ name: "task_members" })
members?: Member[];
@ManyToOne(() => Committee, committee => committee.inChargeOf, { nullable: true })
@JoinColumn({ name: "owning_committee" })
ownedBy?: Committee;
@ManyToMany(() => Committee, committee => committee.tasks, { nullable: true, onDelete: "CASCADE" })
@JoinTable({ name: "task_committees" })
relatedCommittees?: Committee[];
}
Member.ts:
@Entity()
export class Member {
@PrimaryGeneratedColumn()
userId: number;
@Column({ nullable: true })
displayName?: string;
@ManyToMany(() => Committee, committee => committee.members, { nullable: true, onDelete: "CASCADE" })
@JoinTable({ name: "member_of" })
memberOf?: Committee[];
@ManyToMany(() => Committee, committee => committee.leads, { nullable: true, onDelete: "CASCADE" })
@JoinTable({ name: "lead_of" })
leadOf?: Committee[];
@OneToMany(() => Committee, committee => committee.head, { nullable: true, onDelete: "CASCADE" })
headOf?: Committee;
@ManyToMany(() => Task, (task: Task) => task.members, { nullable: true, onDelete: "CASCADE" })
@JoinTable({ name: "tasks_for_member" })
tasks?: Task[];
}
This is how I'm creating the task:
public async createTask(
headCommittee: Committee,
taskDetails: TaskDetails,
relatedCommittees: Committee[] | null,
projectLead: Member | null,
membersToAdd: Member[] | null,
): Promise<Task> {
try {
const task = new Task();
task.title = taskDetails.title;
task.startDate = taskDetails.startDate;
task.endDate = taskDetails.endDate;
task.ownedBy = headCommittee;
if (projectLead) {
task.leads = [projectLead];
}
if (membersToAdd) {
task.members = membersToAdd;
for (const member of membersToAdd) {
member.tasks = [task];
this.memberRepository.save(member);
}
}
if (relatedCommittees) {
task.relatedCommittees = relatedCommittees;
}
console.log(task, "36rm");
await this.taskRepository.save(task);
return task;
} catch (error: unknown) {
// handle
}
}
In light of the issue mentioned, any insights on how to address it would be much appreciated.
Please let me know your thoughts! Thank you.