[TIL] 93일차 _ 번쩍 팀프로젝트 #25

Seoyeon Lee·2026년 2월 13일

Today I Learned ...

오늘은 어제 피드백의 내용을 바탕으로 리팩토링하고, 그 동안의 작업 내용을 문서 정리하는 시간을 가졌다!


🖥️ 번쩍 팀프로젝트 #25

오늘은 어제의 코드 리뷰를 바탕으로 리팩토링을 진행했는데, 그 과정 중에 트랜잭션과 영속성 컨텍스트에 대해 다시 찾아보게 되었다.

우선, 보통의 경우에는 트랜잭션과 영속성 컨텍스트의 생명 주기는 같다.
그래서 하나의 트랜잭션이 마무리되면, 영속성 컨텍스트의 내용도 비워지게 된다.

public class MeetingEvent {
    private Meeting meeting;
}

public class EventListener {

	// 앞선 내용 커밋 후 이벤트 리스너 실행
    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    @EventListener
    public void meetingEventListener(MeetingEvent event) {

        Meeting meeting = event.getMeeting();
		...
    }
}

나는 하나의 기능에서 사용하던 Meeting 객체를 그대로 이벤트에 담아두었고, 해당 기능이 커밋된 후에 이벤트 리스너가 동작하도록 구성하였다.
그런데, 이때 이미 트랜잭션은 끝난 상태이기에 영속성 컨텍스트가 비워져있고, 이 Meeting 객체는 '준영속 상태'가 되어버린다.

Meeting 안에는 Category 객체가 지연 로딩으로 설정되어 있는데, 영속성 컨텍스트 안에서는 Category의 내용을 가져올 때 다시 조회를 해서라도 내용을 가져올 수 있었다.
하지만, 이벤트 리스너에서는 Meeting이 준영속 상태이기에 프록시 객체인 Category의 내용은 가져올 수 없게 되고, 이때 예외까지 생기게 된다.

이런 상황을 방지하기 위해 Meeting 객체를 준영속 상태에서 다시 영속 상태로 만들어야 하는데, 여기에는 두 가지 방법이 있다.
findById로 다시 조회를 하거나 fetch join으로 다른 내용과 함께 조회할 수도 있고,
EntityManager.merge를 통해 준영속을 영속으로 병합할 수도 있다.

아직 EntityManager를 사용하는 것에 익숙하지 않았기 때문에, 나는 다시 조회해오는 것으로 이 문제를 해결했다.
하지만, EntityManager를 직접 컨트롤하면 더 세밀하게 영속성 컨텍스트를 제어할 수 있게 되기 때문에, 이 부분에 대해서는 조금 더 찾아보고, 연습해보려고 한다.

추가로 이벤트 안에 객체 자체를 저장하는 것이 좋을지, 객체의 ID만 저장하는 것이 좋을지에 대해서 여쭤보았는데,
사용하는 상황에 따라 객체 자체를 저장하는 것이 편하다면 객체를 저장해도 된다고 한다.
하지만, 앞선 상황과 같이 지연 로딩이 되어있는 경우에는 문제가 생길 수 있기 때문에, 이 부분을 신경써야 한다.
나는 내가 만들어서 내가 사용하기 때문에 어떤 내용이 안전하고, 어떤 내용이 위험한지 알고 있지만, 다른 사람이 이걸 사용하려고 한다면, 그걸 알지 못하기 때문에 문제가 생길 수 있다.
그래서 사용 가능한 항목을 보여주기 위해 객체 자체를 넣기보다 DTO를 만들어서 넣을 수도 있다고 한다.

그래서 DTO를 만들어 사용할까 했지만, 그러면 다른 내용들을 다 뜯어고쳐야 했기 때문에.. 우선은 Meeting 객체를 그대로 담아 사용하기로 하였다.
대신 Category에 대해서는 fetch join을 통해 처음부터 즉시 로딩으로 내용을 가져오도록 설정해주었다.
다음부터는 이벤트를 사용할 때 해당 내용들을 신경써서 진행해야겠다.

우리 팀이 작성한 코드는 깃허브를 통해 업로드해두었다.
GitHub 보러가기


🙃 오늘의 느낀점

영속성 컨텍스트와 트랜잭션은 스프링을 시작할 때부터 배웠던 내용이다.
그때 그냥 대충 넘어갔더니 이번에 트러블슈팅과 리팩토링을 진행하면서 이게 어떤 내용이었는지 다시 찾아봐야만 했었다.
앞으로는 정말 기본적인 내용들 잘 정리하고, 익혀두어야겠다..

profile
백엔드 개발자 지망생

0개의 댓글