한 테이블의 각 행이 다른 테이블의 하나의 행과만 연관되는 관계를 의미한다. 이는 두 테이블 간의 일대일 대응 관계를 나타낸다. 대표적인 예로는 회원과 프로필 테이블이 있다.
OneToOne 관계는 @JoinColumn() 으로 상대 엔티티의 기본 키를 외래 키로 지정하는데, 엔티티 중 반드시 한 쪽에만 설정해야 한다. 아래 예제에서는, 회원(User)이 프로필(Profile) 엔티티의 기본 키를 참조하는 외래 키를 가진다.
// import 생략
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number
@OneToOne(() => Profile, (profile) => profile.id, {
cascade: true,
eager: true,
onDelete: 'CASCADE',
onUpdate: 'CASCADE'
})
@JoinColumn()
profile: Profile;
}
@Entity()
export class Profile {
@PrimaryGeneratedColumn()
id: number;
@Column()
firstName: string;
@Column()
lastName: string;
@Column()
age: number;
}
- cascade:true
- User 엔티티를 생성하며 동시에 Profile 엔티티 생성이 가능하다.
- 이 옵션이 작성되어있지 않다면 User와 동시에 Profile 엔티티를 생성하려고 할 때 에러가 발생한다.
- eager:true
- User 엔티티를 조회할때 다른 설정을 하지않아도 Profile 정보가 함께 조회된다.
- 이 옵션은 User 엔티티를 로드할 때 관련된 엔티티를 함께 로드하는 옵션이다.
- onDelete:'CASCADE'
- 외래키로 참조한 레코드가 삭제된 경우 해당 레코드로 함께 삭제된다.
- Profile 엔티티가 삭제된 경우, User 엔티티에서 외래키로 참조하고 있는 레코드도 함께 삭제된다.
- 해당 옵션을 지정하지 않은 경우, Profile 엔티티의 레코드를 삭제하려고 시도할때 에러가 발생한다.
- onUpdate:'CASCADE'
- 옵션은 외래키로 참조한 키 값이 업데이트 될 때, 외래 키도 함께 업데이트 된다.
- Profile의 기본 키가 수정되면 User 엔티티의 외래 키도 동일하게 업데이트된다.
- 해당 옵션을 지정하지 않은 경우, Profile 엔티티의 레코드를 수정하여도 외래키가 업데이트되지 않는다.
위와 같이 엔티티를 정의한다면, User 엔티티에서는 연결된 Profile 엔티티를 확인할 수 있지만, Profile 엔티티에서는 연결된 User 엔티티를 확인할 수 없다. Profile 엔티티에서도 User 엔티티를 확인하려면 양방향 관계를 설정해야 한다.
// import 생략
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number
@OneToOne(() => Profile, (profile) => profile.user, {
cascade: true,
eager: true,
onDelete: 'CASCADE',
onUpdate: 'CASCADE'
})
@JoinColumn()
profile: Profile;
}
@Entity()
export class Profile {
@PrimaryGeneratedColumn()
id: number;
@Column()
firstName: string;
@Column()
lastName: string;
@Column()
age: number;
@OneToOne(() => UserEntity, (user) => user.profile)
user: UserEntity;
}
위와 같이 작성한다면, 이제 Profile 엔티티에서 relation을 사용하여 User 엔티티도 함께 조회가 가능하다.
const profile = await this.profileRepository.findOne({
where: { id: 1 },
relations: ['user'],
});
양방향 참조를 설정하면 다음과 같은 이점을 얻을 수 있다.
[참고자료]
https://velog.io/@cabbage/TypeORM-One-to-one-%EA%B4%80%EA%B3%84OneToOne