스프링

JPA 다대일 연관관계에서 연관관계 편의 메서드를 꼭 분리해야 할까?

148june 2025. 5. 2. 11:25

🔹 들어가며

Spring JPA에서 @ManyToOne, @OneToMany 같은 연관관계를 다룰 때, 단순히 Entity를 설정하는 것보다 더 중요한 건 **"연관관계를 어떻게 유지할 것인가"**입니다.

특히 할 일(Todo)을 생성할 때 자동으로 유저(User)를 담당자(Manager)로 등록하는 예처럼, 연관 엔티티를 함께 조작할 일이 많을수록 편의 메서드를 따로 만드는 습관이 중요해집니다.


🔹 문제 상황 예시

public Todo(String title, String contents, String weather, User user) {
    this.title = title;
    this.contents = contents;
    this.weather = weather;
    this.user = user;

    // 할 일 생성 시 유저를 자동으로 담당자로 등록
    this.managers.add(new Manager(user, this));
}

언뜻 보면 간단하고 깔끔해 보이지만, 이 방식은 실수하기 쉬운 구조입니다.


✅ 연관관계 편의 메서드를 분리해야 하는 이유


1. 연관관계 일관성 유지

양방향 연관관계라면 다음 두 가지를 항상 같이 설정해야 합니다.

manager.setTodo(this);
this.managers.add(manager);

이걸 자주 빼먹게 되죠. 그래서 아래처럼 메서드로 묶는 게 안전합니다:

public void addManager(User user) {
    Manager manager = new Manager(user, this);
    this.managers.add(manager);
    // manager.setTodo(this); // 양방향 관계 시 같이 설정
}

2. 중복 제거 & 재사용성 증가

다른 곳에서도 Manager를 추가해야 할 일이 생긴다면?
addManager() 하나로 재사용하면 됩니다.


3. 가독성과 의도 표현

Todo todo = new Todo(...);
todo.addManager(user); // 누가 담당자인지 바로 보임

비즈니스 로직의 의도가 코드에 드러나는 장점이 있습니다.


🔹 실전 예제: Todo 엔티티

@OneToMany(mappedBy = "todo", cascade = CascadeType.PERSIST, orphanRemoval = true)
private List<Manager> managers = new ArrayList<>();

public Todo(String title, String contents, String weather, User user) {
    this.title = title;
    this.contents = contents;
    this.weather = weather;
    this.user = user;
    addManager(user);  // 편의 메서드 사용
}

public void addManager(User user) {
    Manager manager = new Manager(user, this);
    this.managers.add(manager);
}

❌ 메서드 분리가 꼭 필요한 건 아닐 때

  • 단방향 연관관계이고
  • 한 번만 쓰이며
  • 구조가 단순한 경우

→ 이런 상황이라면 생성자 안에 직접 넣어도 무방합니다.
하지만 실무에선 거의 모든 경우 확장 가능성을 고려해야 하므로, 분리 습관을 들이는 게 좋습니다.


✅ 결론: 실수 없는 연관관계 설정을 위한 작은 습관

  • 연관관계가 꼬이지 않게 하려면?

편의 메서드로 분리하자.

  • 유지보수, 가독성, 재사용성까지 잡고 싶다면?

편의 메서드부터 챙기자.