개발
[스프링부트] LazyInitializationException 지연 로딩 오류
BiniForBini
2024. 9. 12. 16:20
흑..흑...
어드민 기능 중 탈퇴 회원을 회원으로 복구하는 로직을 짜다가 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은 정상적으로 실행되지 않았을까.....찝찝해ㅐㅐㅐㅐㅐㅐㅐㅐ