I have the following typescript TypeORM model:
@Entity()
export class Teacher extends EntityBase {
@Column({ length: 256 })
public firstName: string
@Column({ length: 256 })
public lastName: string
@Column({ unique: true, length: 256 })
public email: string
@ManyToMany((type) => Student, (student) => student.teachers, { nullable: true })
@JoinTable()
public students!: Student[]
constructor(first: string, last: string, email: string) {
super();
this.firstName = first;
this.lastName = last;
this.email = email;
//this.students = []; TypeORM initialization failed! InitializedRelationError: Array initializations are not allowed in entity relations
}
}
The following query:
public async AddStudent (teacher: Teacher, student: Student): Promise<Teacher | null> {
if (teacher && student) {
try {
teacher.students.push(student);
return await this.Update(teacher);
} catch (e) { console.log(e); }
}
return null;
}
This is what the Update
does:
public async Update (entity: T): Promise<T | null> {
return await this._repository.save(entity);
}
It failed with exception:
QueryFailedError: duplicate key value violates unique constraint "PK_ec87c1e05d0d8cefa233575cfe1"
at PostgresQueryRunner.query (/usr/src/Node.JSRestAPI/node_modules/typeorm/driver/postgres/PostgresQueryRunner.js:219:19)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async InsertQueryBuilder.execute (/usr/src/Node.JSRestAPI/node_modules/typeorm/query-builder/InsertQueryBuilder.js:106:33)
at async SubjectExecutor.executeInsertOperations (/usr/src/Node.JSRestAPI/node_modules/typeorm/persistence/SubjectExecutor.js:260:42)
at async SubjectExecutor.execute (/usr/src/Node.JSRestAPI/node_modules/typeorm/persistence/SubjectExecutor.js:92:9)
at async EntityPersistExecutor.execute (/usr/src/Node.JSRestAPI/node_modules/typeorm/persistence/EntityPersistExecutor.js:140:21)
at async StudentRepository.Update (file:///usr/src/Node.JSRestAPI/src/infrastructure/build/index.js:107:16)
at async StudentRepository.AddTeacher (file:///usr/src/Node.JSRestAPI/src/infrastructure/build/index.js:147:24)
at async Promise.allSettled (index 1)
at async AddStudentsToTeacherUseCase.Handle (file:///usr/src/Node.JSRestAPI/src/webapi.core/build/index.js:424:50) {
query: 'INSERT INTO "student_teachers_teacher"("studentId", "teacherId") VALUES ($1, $2)',
parameters: [ 1, 1 ],
driverError: error: duplicate key value violates unique constraint "PK_ec87c1e05d0d8cefa233575cfe1"
at /usr/src/Node.JSRestAPI/node_modules/pg/lib/client.js:526:17
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async PostgresQueryRunner.query (/usr/src/Node.JSRestAPI/node_modules/typeorm/driver/postgres/PostgresQueryRunner.js:184:25)
at async InsertQueryBuilder.execute (/usr/src/Node.JSRestAPI/node_modules/typeorm/query-builder/InsertQueryBuilder.js:106:33)
at async SubjectExecutor.executeInsertOperations (/usr/src/Node.JSRestAPI/node_modules/typeorm/persistence/SubjectExecutor.js:260:42)
at async SubjectExecutor.execute (/usr/src/Node.JSRestAPI/node_modules/typeorm/persistence/SubjectExecutor.js:92:9)
at async EntityPersistExecutor.execute (/usr/src/Node.JSRestAPI/node_modules/typeorm/persistence/EntityPersistExecutor.js:140:21)
at async StudentRepository.Update (file:///usr/src/Node.JSRestAPI/src/infrastructure/build/index.js:107:16)
at async StudentRepository.AddTeacher (file:///usr/src/Node.JSRestAPI/src/infrastructure/build/index.js:147:24)
at async Promise.allSettled (index 1) {
length: 264,
severity: 'ERROR',
code: '23505',
detail: 'Key ("studentId", "teacherId")=(1, 1) already exists.',
hint: undefined,
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: 'public',
table: 'student_teachers_teacher',
column: undefined,
dataType: undefined,
constraint: 'PK_ec87c1e05d0d8cefa233575cfe1',
file: 'nbtinsert.c',
line: '663',
routine: '_bt_check_unique'
},
length: 264,
severity: 'ERROR',
code: '23505',
detail: 'Key ("studentId", "teacherId")=(1, 1) already exists.',
hint: undefined,
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: 'public',
table: 'student_teachers_teacher',
column: undefined,
dataType: undefined,
constraint: 'PK_ec87c1e05d0d8cefa233575cfe1',
file: 'nbtinsert.c',
line: '663',
routine: '_bt_check_unique'
}
TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Teacher'
| property 'students' -> object with constructor 'Array'
| index 0 -> object with constructor 'Student'
| property 'teachers' -> object with constructor 'Array'
--- index 0 closes the circle
at JSON.stringify (<anonymous>)
at AddStudentsToTeacherUseCase.Handle (file:///usr/src/Node.JSRestAPI/src/webapi.core/build/index.js:425:76)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async AddStudentsToTeacherController.AddStudentsToTeacher (file:///usr/src/Node.JSRestAPI/build/src/webapi/Controllers/AddStudentsToTeacherController.js:47:21)
::1 - - [06/Jul/2024:09:15:53 +0000] "POST /api/addstudents HTTP/1.1" 400 66 "-" "PostmanRuntime/7.29.4"
JoinTable
must only be on ONE side of the relation.