미해결
Slack 클론 코딩[백엔드 with NestJS + TypeORM]
OneToMany 관계에서 FK 데이터를 Repository를 이용하여 insert시 오류
우선 제 프로젝트에서 구성하고 있는 DB의 일부분입니다. 간단하게 p_references 와 m_references, 그리고 parts 와 models 테이블에 그림파일의 정보를 가지고 있는 images객체의 배열이 필요한데 mysql이다보니 이걸 다 One to Many로 추가시켰습니다. 여기에 images의 각각 대상 테이블에 대한 FK를 nullable : true 상태로 추가시켰습니다. 물론 이렇게 구성하면 images 테이블안에 적어도 한개의 FK를 포함한 입력값만 허용하도록 Guards 를 추가시켜야 될꺼 같습니만... 간단히 이해도를 위해 설명을 추가한거고요.여기서 문제는 p_references/m_reference 와 images table과 연결 시킬때 원래 계획된 대로 images 테이블 안에 string 이나 int 형식의 column이 추가되는것이 아닌 대상 테이블 객체가 잡히는 문제인데요.entities/images.ts@Entity("Images", { schema: "workplaces" })
export class Images {
@PrimaryGeneratedColumn({ type: "int", name: "imageID" })
id: number;
@Column('varchar', { name: 'images', nullable: true })
image: string;
@Column('bool', { name: 'isOwn', nullable: false, default: false })
isOwn: boolean;
@ManyToOne(() => Mreferences, (mreferences) => mreferences.images, { onDelete: "SET NULL", onUpdate: "CASCADE" })
@JoinColumn([{ name: 'modelNumber', referencedColumnName: 'serialNumber' }])
mreferences: Mreferences;
@ManyToOne(() => Preferences, (preferences) => preferences.images, { onDelete: "SET NULL", onUpdate: "CASCADE" })
@JoinColumn([{ name: 'partsNumber', referencedColumnName: 'serialNumber' }])
preferences: Preferences;
@ManyToOne(() => Parts, (parts) => parts.images, { onDelete: "SET NULL", onUpdate: "CASCADE" })
@JoinColumn([{ name: 'partsID', referencedColumnName: 'id' }])
parts: Parts;
@ManyToOne(() => Models, (models) => models.images, { onDelete: "SET NULL", onUpdate: "CASCADE" })
@JoinColumn([{ name: 'modelID', referencedColumnName: 'id' }])
models: Models;
}이것이 images entity에서 설정한 코드입니다. 이렇게 해서 자동으로 생성된 DB 의 ERD가 처음에 올린 스샷으로 제대로 의도된대로 생성된걸 확인할 수 있습니다.기본 설명이 너무 길어졌는데, 이제 여기 강의의 "typeorm 쿼리 빌더" 강의에 나온대로 새로운 데이터를 insert 요청이 발생하면 Images Repository를 이용해서 저장을 하려하는데 문제가 발생드려서 문의드립니다.reference-book.service.tsimport { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Mreferences } from '../entities/Mreferences';
import { Repository } from 'typeorm';
import { ReferencebookModelDto } from './dto/referencebook.model.dto';
import { Videos } from '../entities/Videos';
@Injectable()
export class ReferenceBookService {
constructor(
@InjectRepository(Mreferences)
private referenceModelRepository: Repository<Mreferences>,
@InjectRepository(Images)
private imagesRepository: Repository<Images>,
) { }
async addReferenceModel(addReferenceModel: ReferencebookModelDto) {
const referenceModelBook = new Mreferences();
const referenceModelImages = new Images();
referenceModelBook.serialNumber = addReferenceModel.serialNumber;
referenceModelBook.name = addReferenceModel.modelName;
referenceModelBook.brands = addReferenceModel.brand;
//..... 생략
await this.referenceModelRepository.save(referenceModelBook);
}
}이렇게 작성시, 아무런 문제 없이 FK관련 column 값들을 제외하곤 이상없이 제대로 DB에 저장이 되는데요. 문젠 FK 관련한 값에서 제대로 작동하지 않습니다.const data = new Images() 로 새로 Images객체를 생성하여, ERD에서 처럼 거기에 등록된 modelNumber 값을 입력한 dto객체의 images.image 값으로 지정해주고 저장하면 될 줄 알았는데 실제 생성된 Images객체엔 modelNumber 문자열이 존재하는 대산 mreferences 객체만이 존재합니다. 강의에서 직접 다룬 프로젝트는 아니지만 제가 강의를 보면서 직접 따라하다 발생한 문제라 강의관련 문의에 올렸습니다.어딘가에서 오류가 있던걸까요? 추가로 혹시나 필요할까 해서 dto 파일도 올립니다/dto/referencebook.model.dto.tsimport { ApiProperty } from "@nestjs/swagger";
import { Images } from "../../entities/Images";
import { Brands, Categories } from "../../common/types/enum.types";
import { Videos } from "../../entities/Videos";
export class ReferencebookModelDto {
@ApiProperty({ example: 'WX532433', description: 'Uniq Serial Number', required: true, })
public serialNumber: string;
@ApiProperty({ example: 'Aug-23-2023', description: 'Updated Date', required: true, })
public updateDate: Date;
@ApiProperty({ example: 'Samsung Dryer', description: 'Model Name', required: true, })
public modelName: string;
@ApiProperty({ example: ['afd34323', 'ty23142'], description: 'Serial number List of related parts ', required: false, })
public relatedParts: string[];
@ApiProperty({ example: ['https:/atlanticappliance.com/parts/p?pid=WX532433/image1.jpg'], description: 'Links of own images location', required: false, })
public images: Images[];
@ApiProperty({ example: ['https:/atlanticappliance.com/parts/p?pid=WX532433/video1.mp4'], description: 'Links of own videos location', required: false, })
public videos: Videos[];
@ApiProperty({ example: 'This is a parts for testing model, WX532433', description: 'Scraped description of current product from other sites', required: false, })
public description: string;
@ApiProperty({ example: 'Washer', description: 'Product categories', required: true, })
public category: Categories;
@ApiProperty({ example: '24Inch', description: 'Product Variant Options', required: false, })
public variant: string;
@ApiProperty({ example: '27.7', description: 'Product Weight', required: false, })
public weight: number;
@ApiProperty({ example: 21.49, description: 'Product height', required: false, })
public height: number;
@ApiProperty({ example: 21.49, description: 'Product width', required: false, })
public width: number;
@ApiProperty({ example: 21.49, description: 'Product depth', required: false, })
public depth: number;
@ApiProperty({ example: 'Samsung', description: 'Brand', required: false, })
public brand: Brands;
}