EF Core 객체간 무한참조 발생에 대한 문제

EF Core를 사용하면서 발생했던 무한루프에 대해 설명하고자 글을 작성하게 되었습니다.
아직 배우고 있는 학생이라 글에 부족한 부분이 많아도 이해해주시면 감사하겠습니다…

게시판 서비스를 만들기 위해 User모델을 만들고 있었습니다.
User모델에 사용자의 모든 정보를 넣게 되면 게시판에서 User를 사용할 때 마다 불필요한 사용자 정보를 모두 가져오게 됩니다. 예를 들면 게시판 서비스에서 사용자의 주소는 불필요한 데이터입니다. 이러한 불필요한 데이터를 막기위해 사용자의 정보와 게시판 서비스에서 사용되는 사용자의 정보를 분리하여 UserAvatar를 만들게 되었습니다.

UserAvatar는 1:1관계이면서 필수적 관계입니다.
AvatarUser없이는 존재할 수 없기 때문에 Avatar의 PK로 User의 PK를 사용하였습니다.

public class User {
	public int Id { get; set; }
	public string UserId { get; set; } = string.Empty;
	public string Name { get; set; } = string.Empty;
	public string Email { get; set; } = string.Empty;
	public string PasswordHash { get; set; } = string.Empty;
	public DateTime CreatedDate { get; set; }

	public Avatar Avatar { get; set; } = null!;
}

public class Avatar {
	[ForeignKey(nameof(User))]
	public int Id { get; set; }
	public string NickName { get; set; } = string.Empty;

	public User User { get; init; } = null!;
}

이 모델들을 마이그레이션하고 데이터베이스에 적용하는 것 까지는 아무 문제가 없었습니다.
하지만 UserAvatar는 서로를 참조하고 있기 때문에 데이터를 불러오거나 생성하려고 하면 서로를 게속 참조하게 되었고 다음과 같은 예외가 발생하였습니다.

공식문서 : 관련 데이터 및 serialization에 따르면 일부 직렬화 프레임워크에서는 이러한 무한참조를 허용하지 않는다고 합니다. 제가 사용하고 있는 System.Text.Json은 예외를 발생시킵니다.

무한참조문제를 해결하기 위해서는 서비스 구성에서 Json에 대해 객체간의 무한참조를 무시하도록 설정하거나 무한참조를 발생시키는 탐색속성에서 무한참조를 무시하도록 하는것입니다.

탐색속성이란 위의 User,Avatar모델에서 User.Avatar, Avatar.User입니다.

저는 탐색속성에 [JsonIgnore]특성을 부여하여 객체간에 서로를 무한참조하는 것을 막아 해결하였습니다.

글에서 부족한 부분이나 잘못된 정보가 있다면 알려주세요!
모르는 부분이라면 공부한 뒤 수정해서 반영하도록 하겠습니다!

10개의 좋아요

직렬화의 순환 참조 문제 해결은 속성 마다 JsonIgnore를 수작업으로 부여하는 것보다, 아래의 글을 참고해서 보다 구조적인 방식을 취하는 게 좋을 것 같습니다.

How to preserve references in System.Text.Json - .NET | Microsoft Learn

5개의 좋아요

읽다가 마지막부분에 순환참조의 해결 방안으로 DTO를 제시해주었습니다.

4개의 좋아요

User와 Avatar가 서로 참조하는게 문제 아닐까요?

Entity 객체가 아닌 Dto 객체로 변경하는게 올바른 방법같아요.

3개의 좋아요