Chef.Yeon
Code Cook
Chef.Yeon
전체 방문자
오늘
어제
  • 분류 전체보기 (230)
    • 게임 개발 (1)
      • Unity (1)
    • Android (27)
      • Kotlin (19)
      • 우아한테크코스 5기 (4)
    • Language (11)
      • 파이썬 (3)
      • Java (7)
    • DB (2)
      • SQL (16)
    • Spring (25)
    • 코딩테스트 (56)
    • Git (1)
    • TIL (85)
    • DevOps (6)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 코틀린
  • 우아한테크코스
  • java
  • elasticsearch
  • 코틀린 인 액션
  • 파이썬
  • 백준
  • kotlin
  • 문자열
  • til
  • grafana
  • 안드로이드
  • 프리코스
  • rsocket
  • 내림차순
  • 에라토스테네스의 체
  • 레포지토리
  • ec2
  • 다이나믹 프로그래밍
  • spring
  • Android
  • Docker
  • 코딩테스트
  • MariaDB
  • SQL
  • webflux
  • enum
  • kibana
  • Wil
  • 프로그래머스

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Chef.Yeon

Code Cook

[TIL - 20230428] failed to lazily initialize a collection of role
TIL

[TIL - 20230428] failed to lazily initialize a collection of role

2023. 4. 28. 23:02

 

💻문제점


@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Member {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "member_id")
    private Long id;

    @Column(nullable = false)
    private String userId;

    @Column(nullable = false)
    private String password;

    @Column(nullable = false)
    private String email;

    @Column(nullable = false)
    private String nickname;

    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private JobEnum job;

    @OneToOne(mappedBy = "member", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JsonManagedReference
    private Profile profile;

    @OneToMany(mappedBy = "member", cascade = CascadeType.ALL)
    private List<JoinChatRoom> joinChatRooms = new ArrayList<>();

    @Builder
    public Member(String userId, String password, String email, String nickname, JobEnum job) {
        this.userId = userId;
        this.password = password;
        this.email = email;
        this.nickname = nickname;
        this.job = job;
    }

    public void addChatRoom(JoinChatRoom joinChatRoom) {
        this.joinChatRooms.add(joinChatRoom);
    }
}

 

//채팅방 생성
public ResponseDto createChatRoom(String receiver, Member member) {
    ChatRoom chatRoom = new ChatRoom(receiver);
    JoinChatRoom joinChatRoom = new JoinChatRoom(member, chatRoom);
    member.addChatRoom(joinChatRoom);
    chatRoomRepository.save(chatRoom);
    return ResponseDto.setSuccess("create chatRoom success", chatRoom);
}

 

채팅방을 생성해 사용자가 참여한 채팅방을 joinChatRooms에 add 하려고 했다.

이때 joinChatRooms는 Member와 ChatRoom의 중간 테이블이며, Member와 ChatRoom은 양방향 연관 관계이다.

그런데 문제가 발생

 

PostMan을 통해 다음과 같이 요청을 했다.

 그리고 콘솔에 발생한 에러

failed to lazily initialize a collection of role: edit.edit.entity.Member.joinChatRooms: could not initialize proxy - no Session
	at org.hibernate.collection.spi.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:635) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
	at org.hibernate.collection.spi.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:218) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
	at org.hibernate.collection.spi.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:615) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
	at org.hibernate.collection.spi.AbstractPersistentCollection.write(AbstractPersistentCollection.java:442) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
	at org.hibernate.collection.spi.PersistentBag.add(PersistentBag.java:385) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]

📃시도

찾아보다가 '사용할 때 영속성 컨텍스트가 종료되어서 지연 로딩을 할 수 없어 발생하는 오류' 라는 말에 해당 메서드에 트랜잭션이 잘 되어있는지 확인해보았다. 클래스에 @Transactional을 붙인 상태라 해당 문제는 아닌 것으로 판단...

@Service
@Slf4j
@RequiredArgsConstructor
@Transactional
public class ChatService {

    private final ChatRoomRepository chatRoomRepository;

    /**
     * 채팅방 생성
     */
    public ResponseDto createChatRoom(String receiver, Member member) {
        ChatRoom chatRoom = new ChatRoom(receiver);
        JoinChatRoom joinChatRoom = new JoinChatRoom(member, chatRoom);
        member.addChatRoom(joinChatRoom);
        chatRoomRepository.save(chatRoom);
        return ResponseDto.setSuccess("create chatRoom success", chatRoom);
    }
    /* ... */
}

🔍해결

지연 로딩으로 인해 생성된 프록시 객체를 초기화 하지 못한 것. 즉 연관 데이터를 가져오는 것에 실패한 것이다.

fetch 타입은 EAGER로 바꾸어 Member 조회시 연관된 데이터를 함께 가져오도록 하였다.

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Member {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "member_id")
    private Long id;

    @Column(nullable = false)
    private String userId;

    @Column(nullable = false)
    private String password;

    @Column(nullable = false)
    private String email;

    @Column(nullable = false)
    private String nickname;

    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private JobEnum job;

    @OneToOne(mappedBy = "member", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JsonManagedReference
    private Profile profile;

    @OneToMany(mappedBy = "member", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private List<JoinChatRoom> joinChatRooms = new ArrayList<>();

    @Builder
    public Member(String userId, String password, String email, String nickname, JobEnum job) {
        this.userId = userId;
        this.password = password;
        this.email = email;
        this.nickname = nickname;
        this.job = job;
    }

    public void addChatRoom(JoinChatRoom joinChatRoom) {
        joinChatRooms.add(joinChatRoom);
    }
}

 

PostMan으로 확인하면 채팅방이 정상정으로 생성되고 추가된다.

728x90

'TIL' 카테고리의 다른 글

[TIL - 20230429] WebSocket + Stomp 적용기2  (0) 2023.04.29
[TIL - 20230428] WebSocket + Stomp 적용기1  (0) 2023.04.29
[TIL - 20230427] message properties 사용한 @Valid 메시지 처리  (0) 2023.04.27
[TIL - 20230426] Enum 타입 필드 검증을 위한 커스텀 애노테이션 생성  (0) 2023.04.26
[TIL - 20230420] ControllerAdvice, ExceptionHandler 전역 예외 처리  (0) 2023.04.20
    'TIL' 카테고리의 다른 글
    • [TIL - 20230429] WebSocket + Stomp 적용기2
    • [TIL - 20230428] WebSocket + Stomp 적용기1
    • [TIL - 20230427] message properties 사용한 @Valid 메시지 처리
    • [TIL - 20230426] Enum 타입 필드 검증을 위한 커스텀 애노테이션 생성
    Chef.Yeon
    Chef.Yeon
    보기 좋고 깔끔한 코드를 요리하기 위해 노력하고 있습니다.

    티스토리툴바