인프런 커뮤니티 질문&답변

NoobDev님의 프로필 이미지
NoobDev

작성한 질문수

Slack 클론 코딩[백엔드 with NestJS + TypeORM]

typeorm 관계 설정하기

엔티티에서 관계 맺을 때 질문...

작성

·

182

0

@Column('int', { name: 'OwnerId', nullable: true })
OwnerId: number | null;


@ManyToOne(() => Users, (users) => users.Workspaces, {
onDelete: 'SET NULL',
onUpdate: 'CASCADE',
})
@JoinColumn([{ name: 'OwnerId', referencedColumnName: 'id' }])
Owner: Users;


https://github.com/ZeroCho/sleact/blob/master/nest-typeorm/src/entities/Workspaces.ts 에서 코드 가져왔습니다.

name: "ownerId"가 서로 중복되어서 들어가 있는데, 이거를 어떻게 이해할 수 있을까요? --> 컴파일 과정에서 오류가 나지 않는 것이 궁금하다 이것입니다. 최소한 ambigious하다고 오류가 나야할 것만 같은 코드로 보입니다.

https://www.inflearn.com/questions/248521 에서 보니 굳이 join을 하지 않고  참조 및 수정을 하기 위한 것으로 보이는데, (실제로 제로초님의 서비스를 보니 join 없이 senderId, ownerId 와 같이 바로바로 수정하는 것을 봤습니다.)

joinColumn을 바로 수정하게 되면 join을 하지 않고도 그 안의 정보들이(실제 join되는) 수정 및 참조가 가능한 것인가요?

//그런데 질문을 올리고 다시 생각해보니 @joinColumn은 자동으로 ownerId를 만들어 줄텐데, join column에서도 생성되고, 이미 생성을 또 해놓았는데 음... 사실 이 엔티티가 잘 이해가 되지 않습니다.

//또 추가로 ManyToOne에서는 적지 않아도 joinColumn을 자동으로 만들어준다고 하면, 위의 코드를 이렇게만 적어도 문제가 안되지 않나 싶기도 합니다...

  @ManyToOne(() => Users, (users) => users.Workspaces, {
    onDelete: 'SET NULL',
    onUpdate: 'CASCADE',
  })
  Owner: Users;

//아니면 저렇게 적는 것이 join을 하지 않아도 joinColumn을 유지하기 위한 것인가요? --> 혹시 그렇다면 컴파일 과정에서 오류는 없는지 궁금합니다.

 

질문이 굉장히 두서없는 점 죄송합니다...

군대에서 연등시간에만 보고 빠르게 적고 하다보니 충분한 이해없이 질문한 거라면 죄송합니다.

답변 1

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

OwnerId는 실제로 존재하는 컬럼이고, Owner는 join 후에 생성되는 속성입니다(실제 컬럼이 아닙니다). 그래서 둘 다 적어준 것이고 공존이 가능한 것이고요.

Owner만 존재해도 되긴 하는데 OwnerId에 값을 직접 넣을 수는 없으므로 OwnerId를 따로 만들어서 직접 컨트롤할 수 있게 한 겁니다.

 joinColumn을 바로 수정한다, joinColumn을 유지한다, joinColumn을 자동으로 만들어준다 전부 다 잘못된 말이라서 질문이 정확히 무엇인지 잘 모르겠습니다.

NoobDev님의 프로필 이미지
NoobDev
질문자

이게 연등실에서 시간이 없어서 급하게 작성한 질문이니 제가 봐도 말이 이상하네요...

1. Owner가 가상의 컬럼인것은 아는데, owner가 생성되면서 joinColumn때문에 ownerId도 생성이 될 텐데, 이때는 이미 있는 ownerId와 겹쳐서 문제는 일으켜야 할 법한데 일으키지 않는 것이 궁금합니다. -> "Owner만 존재해도 되긴 하는데 OwnerId에 값을 직접 넣을 수는 없으므로 OwnerId를 따로 만들어서 직접 컨트롤할 수 있게 한 겁니다." 이것이 가능한 이유가 궁금하다 이겁니다...

2. save 즉 CREATE을 할때는 ownerId와 같은 속성에 id를 넣는데, workspace.owner = owner(User 타입을 가진) 대신에 workspace.ownerId = ownerId(string 타입을 가진)을 하게 되었을 때, 자동으로 ownerId에 맞게 owner 컬럼도 변화하는지 궁금합니다.

workspace.owner = owner <- sequelize를 쓰다가 typeorm을 처음 쓸때, 이런식으로만  예제를 봐와서 그런지, owner에 값을 입력안하고 ownerId에 string 타입을 입력한다고 owner도 저절로 변하는지 궁금합니다...  (아마 깃허브 코드를 보니 다 그렇게 작성하신 걸 보면 변하는 것 같아보이긴 합니다, 예상컨데 join하면서 ownerId로 join을 하게되어서 그런것 같기는 한데...)

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

1. 가능한 이유는 그렇게 가능하도록 typeorm이 만들어졌기 때문입니다. 안 돼야 하는 이유가 있나요? joinColum이 ownerId가 없으면 자동 생성하는 것도 맞지만, id 컬럼을 명시했다고 해서 충돌이 일어나는 이유는 아닙니다만

2. owner 속성에 값을 넣어서 생성하는 것은 owner까지 같이 생성해 워크스페이스와 연결하는 것이고요. ownerId에 오너 아이디만 넣는 것은 이미 생성된 오너를 워크스페이스에 연결하는 겁니다. 둘은 완전 다른 동작입니다. 저절로 변한다 이런 개념은 없습니다. create 시의 동작은 join이 아닙니다. join은 select 시의 동작입니다.

NoobDev님의 프로필 이미지
NoobDev
질문자

감사합니다.

1,2번 둘다 많은 도움이 됐고, 2번에서 제가 크게 오해를 하고 있었네요... 감사합니다...

NoobDev님의 프로필 이미지
NoobDev

작성한 질문수

질문하기