본문 바로가기

개발

[스프링부트] LazyInitializationException 지연 로딩 오류

흑..흑...

어드민 기능 중 탈퇴 회원을 회원으로 복구하는 로직을 짜다가 DeletedMember로 불러온 List인 DeletedProfile을 불러오는 과정에서 오류 발생

 

"trace": "org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.example.domain.deleted.entity.DeletedMember.deletedProfiles: could not initialize proxy - no Session ...

 

 

[module-admin] → DeletedMember

@NoArgsConstructor
@Getter
@Entity
@Table(name = "deleted_member")
public class DeletedMember {
    @Id
    @Column(name = "deleted_member_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private Long member_code; // member에서 사용하는 pk(id)값

    private String email;

    private String nickname;

    private String phone;

    @Enumerated(EnumType.STRING)
    private Gender gender;

    @Column
    private String password;

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate birthday;

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @Column(name = "created_at")
    private LocalDate createdAt;

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @Column(name = "cancelled_at")
    private LocalDate cancelledAt;

    @Enumerated(EnumType.STRING)
    private Role role;

    @Enumerated(EnumType.STRING)
    private Provider provider;

    @OneToMany(mappedBy = "deletedMember", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<DeletedProfile> deletedProfiles = new ArrayList<DeletedProfile>();
    
}

 

 

[module-admin] → DeletedProfile

@NoArgsConstructor
@Getter
@Entity
@Table(name = "deleted_profile")
public class DeletedProfile {

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

    @JsonIgnore
    @ManyToOne(fetch = LAZY)
    @JoinColumn(name = "deleted_member_id")
    private DeletedMember deletedMember;

    @Column
    private Long profile_id; // 기존 profile_id

    @Column
    private String nickname;

    @Enumerated(EnumType.STRING)
    private Gender gender;

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate birthday;

    @Column
    private Boolean owner; // 본인인지, 아닌지 True, False

    @Enumerated(EnumType.STRING)
    private Choice pregnancy;

    @Enumerated(EnumType.STRING)
    private Choice smoking;

    @Enumerated(EnumType.STRING)
    private Choice hypertension;

    @Enumerated(EnumType.STRING)
    private Choice diabetes;
}

 

 

fetch 타입을 LAZY로 사용해서 발생한 오류로 프록시 객체 값을 사용하여 발생한 오류다.

 

해결 방법으로는 크게 두가지 방법이 있다.

 

1. Service 단에 @Transactional 추가

2. fetch 타입 EAGER으로 변경

 

>> EAGER을 사용하는건 성능 상 좋지 않을 것 같아서 @Transactional 방법으로 해결하고 싶었는데 자꾸 동일한 오류가 발생한다.

@Transactional말고 FetchJoin을 사용하여 repository에서 해당 데이터를 불러올 때 DeletedMember와 List값을 함께 불러오는 방법이다

 

@Query("SELECT dm FROM DeletedMember dm JOIN FETCH dm.deletedProfiles WHERE dm.id = :id")
Optional<DeletedMember> findByIdWithProfiles(@Param("id") Long id);

 

 

정상적으로 실행하는걸 볼 수 있다.

왜 @Transactional은 정상적으로 실행되지 않았을까.....찝찝해ㅐㅐㅐㅐㅐㅐㅐㅐ