inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

자바 ORM 표준 JPA 프로그래밍 - 기본편

LazyInitializationException 원인을 알 수 있을까요..

718

한희성

작성한 질문수 10

0

안녕하세요 

양방향 연관관계와 연관관계의 주인 1- 기본 7분 파트 수업 진행중입니다 

Optional<Member> byId = memberRepository.findById(1L);

여기 까진 제대로 호출이 되어 아래 조인이 제대로 수행 되는 것을 확인 하였습니다.

    select

        member0_.member_id as member_i1_1_0_,

        member0_.city as city2_1_0_,

        member0_.name as name3_1_0_,

        member0_.street as street4_1_0_,

        member0_.team_id as team_id6_1_0_,

        member0_.zipcode as zipcode5_1_0_,

        team1_.team_id as team_id1_4_1_,

        team1_.name as name2_4_1_ 

    from

        member member0_ 

    left outer join

        team team1_ 

            on member0_.team_id=team1_.team_id 

    where

        member0_.member_id=?

문제는 다음 소스에서

List<Member> member = byId.get().getTeam().getMembers();

for (Member member1 : member) {
System.out.println(member1.getName());
}

System.out.println() 으로 값을 확인하려하면 예외가 일어나고 있습니다.. ㅠ

맴버 객체

@JoinColumn(name = "team_id")
@ManyToOne(cascade = CascadeType.ALL)
private Team team;

팀 객체

@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();

다음과 같이 설정 하였습니다.

java JPA

답변 4

1

김영한

희성님 많은 부분을 이해하셨군요^^

지금 스프링으로 강의를 따라하고 계신 것이여서 답을 드리자면

@Transactional을 다음과 같이 붙여주세요.

@Service

@Transactional

public class JpaService {}

스프링과 JPA를 함께 사용하면 트랜잭션 범위 안에서 영속성 컨텍스트를 생성하고 관리합니다.

트랜잭션이 종료되면 영속성 컨텍스트도 함께 종료되기 때문에 연관된 엔티티들을 지연로딩(LAZY) 할 수 없습니다.

그래서 LazyInitializationException 예외가 발생한 것이지요.

이 부분에 대한 더 자세한 이해는 프록시 부분에서 설명드립니다.

감사합니다.

0

한희성

바로 다음 강의 듣고 있는 상황에서 에러가 해결과 어느 부분이 잘못되었는지 해결 되었습니다.

디폴트가 lazy 상태라 객체를 사용하는 시점에 영속성에  있지 않아 no session 에러가 나왔으며

@OneToMany(mappedBy = "team",fetch = FetchType.EAGER)
private List<Member> members = new ArrayList<>();

로 수정 후 처음엔 객체 무한 루프가 도는 상황이 발생되더라고요 

바로 다음 강의 양방향 연관관계와 연관관계의 주인 2 - 주의점, 정리  를 듣는 과정에서 

@toString 으로 객체를 확인 할 시 무한루프에 빠진다는 주의점을 깨달았으며

@toString 을 지운 후 

for (Member member1 : members) {
System.out.println(member1.getName());
}

를 호출 시 정상 적으로 객체 탐색이 되는 것을 확인하였습니다.

제가 이해한것이 맞을까요 ?

0

한희성

스프링 부트로 프로젝트를 만들어서 실습중입니다.. 소스가 다시 차이가 있음을 죄송합니다..ㅠㅠ

컨트롤러에서 호출 

package jpabasic.ex1hellojpa.service;

import jpabasic.ex1hellojpa.domain.Member;
import jpabasic.ex1hellojpa.domain.Team;
import jpabasic.ex1hellojpa.repository.JpaTestRepository;
import jpabasic.ex1hellojpa.repository.MemberRepository;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;


@Service
public class JpaService {

final private JpaTestRepository jpaTestRepository;
final private MemberRepository memberRepository;
private JpaService(JpaTestRepository jpaTestRepository
, MemberRepository memberRepository){
this.jpaTestRepository = jpaTestRepository;
this.memberRepository = memberRepository;
}

public void createTest() {
Team team = new Team();
team.setName("team1");
System.out.println("================");
jpaTestRepository.save(team);
System.out.println("================");
System.out.println(team.getId());
System.out.println("테스트");
}


public void createMember() {
Member member = new Member();
member.setName("홍길동");
member.setCity("서울");
member.setZipcode("1234");

Team team = new Team();
team.setName("A ");

member.setTeam(team);
memberRepository.save(member);
System.out.println(member.getId());
}

public void selectMember(){
Optional<Member> byId = memberRepository.findById(1L);
List<Member> members = byId.get().getTeam().getMembers();

for (Member member1 : members) {
//에러
System.out.println(member1.getName());
}

}

}

team 객체

package jpabasic.ex1hellojpa.domain;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@ToString
@Getter
@Setter
@Entity
public class Team {

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

private String name;

@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();
}

member 객체

package jpabasic.ex1hellojpa.domain;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import javax.persistence.*;

@Getter
@Setter
@ToString
@Entity
public class Member {

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

@JoinColumn(name = "team_id")
@ManyToOne(cascade = CascadeType.ALL)
private Team team;

private String name;

private String city;

private String street;

private String zipcode;
}

0

김영한

안녕하세요. 희성님

main 메서드 전체 코드를 보여주시겠어요?

inheritance startegy 선택시 고려사항

0

11

0

Entity 동등성 비교

0

14

1

실무 조언 관련 질문입니다.

0

41

1

H2데이터베이스 파일 생성

0

52

2

서브쿼리 강의에서 ALL 예시 관련 질문드립니다.

0

49

2

수정또는 삭제시 영속성 엔티티에 값이 무조건 있어야 하나요?

0

48

1

JPQL 메소드와 락

0

53

1

Delivery @OneToOne

0

57

1

17강 4~5분대 테이블 값 조회가 안됩니다.

0

89

2

UnsupportedOperationException 발생

0

82

3

H2 Database 연결이 안됩니다.

0

89

2

연관관계 매핑 질문드립니다.

0

82

2

h2데이터베이스 실행오류

0

105

2

persistence.xml

0

103

2

양방향 연관관계에서 연관관계의 주인(mappedBy)을 왜 꼭 정해야 하나요?

0

77

1

영속성 컨텍스트

0

62

1

JPA 프록시

0

90

1

Native Query와 MyBatis

0

63

1

영속성 컨텍스트는 어떤 메모리에 저장되는건가요?

0

84

1

임베디드 타입 예시 코드 관련 질문

0

112

3

명시적 조인에서 별칭을 주면 왜 객체에 접근할 수 있나요

0

91

3

인텔리제이 패키지 커서 단축키 질문

0

106

2

혹시 현재는 ID 데이터 타입이 String이면 안되나요?

0

137

1

양방향 연관관계 시 연관관계 주인을 설정하는 이유

0

68

1