1 분 소요

문제 발생 상황

마지막으로 회원탈퇴 기능을 구현하던 중에 발생했다. 아무래도 회원탈퇴를 하려면 회원과 연관된 모든 entity의 정보를 함께 지워줘야 하므로 UserService 클래스에서 연관된 각 entity에 대해 삭제하는 기능을 사용할 수 있도록 Service 클래스를 다 선언해줬는데, 이미 서로 참조하는 케이스가 있어서 다음의 에러가 발생했다.

the dependency of some of the beans in the application context form a cycle
public class UserService {

    private final UserRepository userRepository;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    private final PostService postService;
    private final FollowService followService;
    private final LikeService likeService;
    private final CommentService commentService;
    private final NotificationService notificationService;
    ...
}

public class PostService {

    private final PostRepository postRepository;
    private final UserService userService;
    private final CommentService commentService;
    ...
}

public class CommentService {

    private final CommentRepository commentRepository;
    private final UserService userService;
    private final PostService postService;
    ...
}

출처: https://ch4njun.tistory.com/269


해결

찾아보니까 이 에러를 강제로 무시하는 설정도 있다고 하는데, spring 버전이 올라가면서 순환 참조를 금지하도록 설정했다고 하니 굳이 할 필요는 없을 것 같아 순환 참조 구조를 끊는 방법을 택하기로 했다. 지금까지는 각 entity Service 클래스에서 만약 다른 entity에 대한 기능을 필요로 할 경우 Service 클래스를 바로 필드로 써왔지만, 상당 수의 기능들이 Repository에 구현된 함수를 그대로 호출만 하는 함수가 있어서 굳이 Service를 끌어와서 순환 참조 구조를 만들지 말고, Repository에 정의된 함수를 사용하는 걸로 충분하다면 해당 entity의 Repository를 필드로 가져와 직접 그 함수를 사용하는 방법으로 수정했다.

즉, 나같은 경우 각 entity Service 클래스에서 서로를 필드로 정의해놓고 사용하는 케이스가 있어서 순환 참조 구조가 발생했었다. 이 구조를 깨기 위해서 무조건 타 entity 기능을 쓰기 위해 Service를 필드로 정의하지 말고 Repository를 정의해서 사용하도록 해 순환 참조 구조를 깨서 문제를 해결했다.

Reference

카테고리:

업데이트:

댓글남기기