node.js - TypeORM - OneToOne 조인으로 업데이트 시 관련 레코드 삭제 시도
저는 TypeORM을 사용하는 프로젝트가 있으며 다음 두 개의 엔티티가 있습니다:
@Entity("Email")
export class EmailEntity extends BaseEntity implements IEmail {
@Column({length: 100}) to: string;
@Column({length: 100}) from: string;
@Column({length: 255}) subject: string;
@Column({nullable: true}) html: string;
@Column({nullable: true}) text: string;
}
그리고
@Entity("QueuedEmail")
export class QueuedEmailEntity extends BaseEntity implements IQueuedEmail {
@OneToOne(email => EmailEntity, {nullable: false, cascadeAll: true})
@JoinColumn()
email: EmailEntity;
@Column() retryCount: number;
@Column() status: QueuedEmailStatus;
constructor() {
super();
this.retryCount = 0;
this.status = QueuedEmailStatus.QueuedForDispatch;
}
}
`BaseEntity`는 `@PrimaryGeneratedColumn`이 있는 `id` 컬럼을 가진 추상 클래스입니다.
다음 코드는 QueuedEmail의 status를 업데이트합니다:
const queuedEmailEntityArray: QueuedEmailEntity[] =
await this.queuedEmailRepository.createQueryBuilder("queuedEmail")
.where("queuedEmail.status = :queuedEmailStatus", {queuedEmailStatus: QueuedEmailStatus.QueuedForDispatch})
.innerJoinAndSelect("queuedEmail.email", "email")
.orderBy("queuedEmail.id", "DESC")
.getMany();
queuedEmailEntityArray.forEach(async (value, index) => {
let queuedEmailEntity: QueuedEmailEntity = queuedEmailEntityArray.pop();
queuedEmailEntity.status = QueuedEmailStatus.AttemptingToDispatch;
await this.queuedEmailRepository.persist(queuedEmailEntity);
});
이제 select는 배열 또는 QueuedEmailEntity 객체를 올바르게 로드하며, forEach는 실행되지만 다음 예외를 발생시킵니다:
query failed: DELETE FROM "Email" WHERE "id"=$1 -- PARAMETERS: [1] error during executing query:error: update or delete on table "Email" violates foreign key constraint "fk_d438362cf2adecbcc5b17f45606" on table "QueuedEmail"
디버그 쿼리 출력은 TypeORM이 status 필드를 업데이트하면서 emailId도 업데이트하고 EmailEntity 레코드를 삭제하려고 시도하고 있음을 보여줍니다.
UPDATE "QueuedEmail" SET "status"=$1, "emailId"=$2 WHERE "id"=$3 -- PARAMETERS: [1,1,1]
DELETE FROM "Email" WHERE "id"=$1 -- PARAMETERS: [1]
나는 TypeORM이 내가 참조를 변경하지도 않았는데 왜 emailId 필드를 업데이트해야 하는지 이해가 되지 않는다. 더구나 여전히 참조되는 레코드를 왜 삭제하려고 하는지도 이해가 되지 않는다. 위 코드에서 무엇이 잘못되었는지 누가 볼 수 있는가?