failed to lazily initialize a collection of role 오류 관련 문의
20751
17 câu hỏi đã được viết
안녕하세요. 항상 친절하고 정확한 답변 감사합니다.
지금 작업하다가 발생한 오류로 헤매고 있어서 질문드립니다.
소셜로그인으로 로그인 시 기존 회원정보가 없으면 생성하고 나서 소셜로그인 정보 생성하고,
기존 회원정보 있으면 해당 회원정보로 소셜로그인 정보를 생성하려고 합니다. (MemberService.java)
기존에 없는 회원일때 회원정보 생성하고 나서 소셜로그인 정보 생성하는건 잘 되는데,
이미 있는 경우에 기존회원정보를 member에 담아놓고 그걸로 소셜로그인 정보 생성할때 아래와 같은 오류가 발생합니다.
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: kr.soleo.mall.base.domain.member.entity.Member.memberSocialProfiles, could not initialize proxy - no
...
수업들은거 잘 생각해서 구현했다고 생각했는데, 무슨 이유인지 모르겠네요. ㅠㅠ
Member.java
@Entity
@Table(name = "member")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString(of = {"id", "email", "username", "age"})
public class Member extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "member_id")
private Long id;
private String email;
private String password;
private String username;
private int age;
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL)
List<MemberAuth> memberAuths = new ArrayList<>();
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL)
List<MemberSocialProfile> memberSocialProfiles = new ArrayList<>();
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL)
List<Board> boards = new ArrayList<>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "team_id")
private Team team;
public Member(String username) {
this(username, 0);
}
public Member(String username, int age) {
this(username, age, null);
}
public Member(String username, int age, Team team) {
this.username = username;
this.age = age;
if (team != null) {
changeTeam(team);
}
}
//연관관계 메쏘드
public void changeTeam(Team team) {
this.team = team;
team.getMembers().add(this);
}
@Builder
public Member(String email, String password, String username, int age, Team team) {
this.email = email;
this.password = password;
this.username = username;
this.age = age;
if (team != null) {
changeTeam(team);
}
}
}
MemberSocialProfile.java
@Entity
@Table(name = "member_social_profile")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class MemberSocialProfile extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "member_social_profile_id")
private Long id;
private String identifier; //소셜로그인시 id값
private String photourl; //소셜로그인시 프사이미지 URL
private String email;
@Enumerated(EnumType.STRING)
private SocialType socialType; //facebook, kakao, google, naver
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;
//연관관계 메쏘드
public void changeMember(Member member) {
this.member = member;
member.getMemberSocialProfiles().add(this);
}
@Builder
public MemberSocialProfile(SocialType socialType, String identifier, String photourl, String email, Member member) {
this.socialType = socialType;
this.identifier = identifier;
this.photourl = photourl;
this.email = email;
if (member != null) {
changeMember(member);
}
}
}
MemberService.java
@Service
//@RequiredArgsConstructor
@Component
@Configurable
public class MemberService implements UserDetailsService {
@Autowired
private MemberRepository memberRepository;
@Autowired
private MemberAuthRepository memberAuthRepository;
@Autowired
private MemberSocialProfilesRepository memberSocialProfilesRepository;
@Autowired
private PasswordEncoder passwordEncoder;
@Transactional
public void createSocialAccount(MemberDto account) throws Exception {
Member member = null;
if (memberRepository.existsByEmail(account.getEmail())) { //1) member에 해당 이메일로 회원정보가 있으면 그 정보 이용해서 소셜정보생성
member = memberRepository.findByEmail(account.getEmail());
} else { //2) member에 해당 이메일로 회원정보가 없으면 회원정보 생성하고 소셜정보 생성
account.setPassword(passwordEncoder.encode(account.getPassword()));
member = Member.builder()
.email(account.getEmail())
.password(account.getPassword())
.username(account.getUsername())
.build();
memberRepository.saveAndFlush(member);
memberAuthRepository.saveAndFlush(
MemberAuth.builder()
.authType(AuthType.USER)
.member(member)
.build()
);
}
// 1) 조건인 경우 오류발생, 2) 조건인 경우 정상 저장 완료
memberSocialProfilesRepository.saveAndFlush(
MemberSocialProfile.builder()
.identifier(account.getIdentifier())
.photourl(account.getPhotourl())
.email(account.getEmail())
.socialType(account.getSocialType())
.member(member)
.build()
);
}
}
Câu trả lời 3
7
안녕하세요. 조호영님^^
org.hibernate.LazyInitializationException 이 오류는 member를 조회까지는 성공했는데, member.get MemberSocialProfiles() 를 호출해서 사용할 때 영속성 컨텍스트가 종료되어 버려서, 지연 로딩을 할 수 없어서 발생하는 오류 입니다. JPA에서 지연로딩을 하려면 항상 영속성 컨텍스트가 있어야 하거든요.
보통 트랜잭션 밖에서 member를 조회하면 이런 문제가 발생합니다. 그런데 현재 코드만 보면 트랜잭션 안에서 조회한 것 처럼 보입니다. 트랜잭션이 해당 서비스에서 정상 처리 되는지 먼저 확인해보시겠어요?
그래도 잘 안되면, 동작하는, 그리고 실패하는 테스트 코드를 작성해서 전체 프로젝트를 압축해서 올려주세요.
감사합니다.
0
와.. 구글링하다 여기까지 왔는데 아무리 찾아봐도 fetch를 eager로 변경하라는 답변밖에 없었는데
@Transactional로 한방에 해결되었네요.
0
와... 안녕하세요 구글링하다 이 글에 왔는데
'사용할 때 영속성 컨텍스트가 종료되어 버려서, 지연 로딩을 할 수 없어서 발생하는 오류 입니다.'
에 힌트를 얻어 제가 가지고있던 문제 해결에 성공했습니다!
감사 인사를 여기에라도 남깁니다. 좋은 하루 되세요!
3
안녕하세요. 답변 감사합니다.
트랜잭션 말씀하셔서 소스 다시 봤더니 createSocialAccount 메쏘드에는 @Transaction 어노테이션 적용했는데 저걸 호출하는 메쏘드에는 안했네요. 이부분 추가했더니 정상 처리됩니다.
@Transactional // <-- 이부분이 없었어요.
public void setOauth2Member(MemberDto account) throws Exception {
memberSocialProfile = memberSocialProfilesRepository.findByIdentifier(account.getIdentifier());
if(memberSocialProfile == null) {
createSocialAccount(account);
}
}
그런데 이해가 안가는게, 위 호출부분에 @Transaction 없었을때, 질문과 같이 한번 생성은 되고 이후에 오류가 났는데 안되려면 초기 생성도 안되어야 하는거 아닌가요?
강의 관련 외 질문입니다.
0
62
2
SpringBoot4 + Hibernate7 모듈 등록 방법 공유
0
85
1
BeanCreationException
0
86
3
Update 후 UpdateMemberResponse 매핑할 때
0
46
1
트랜잭션을 사용 안 할 때 커넥션은 언제 가져오나요?
0
96
2
페이징 + 검색조건 관련해서 질문드립니다.
0
70
1
Query Dsl Q파일 질문입니다.
0
81
1
루트 쿼리라는것은
0
58
1
메서드를 분리하는 기준
0
61
1
findAllWithMemberDelivery 메서드 질문드립니다.
0
108
3
연관관계 매핑을 안 쓸 경우, 사용해야 하는 전략
0
83
2
fetch join과 영속화와 OSIV의 관계
0
83
2
Distinct 사용 전 결과에 대한 의문
0
112
2
레포지토리 계층에서의 트랜잭션에 대한 의문
0
55
1
영속성 컨텍스트 생명주기의 신기한 부분이 있습니다.
0
77
2
dto 필드 속 엔티티 여부
0
58
1
뷰템플릿 사용 시
0
76
2
Result 클래스 관련 질문
0
56
1
@PostConstruct 프록시 관련 질문드립니다
0
85
1
DTO 대신 Form 사용은 안되나요?
0
133
1
OSIV ON 상태일 때
0
94
1
fetch join VS fetch join 페이징 궁금증
0
179
2
양방향 연관관계 알아보는 법?
0
103
1
16강 17강 간단 정리 이게 맞을까요 ?
0
161
2

