inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

영속성 컨텍스트와 LAZY 로딩 관계

341

epfvkdlxj1

작성한 질문수 9

0

안녕하세요. 영한님
강의를 듣고 궁금한점이 있어서 질문드립니다.
영속성 컨텍스트와 Proxy, LAZY 강의를 들었을 때 Member 엔티티안에 Team 엔티티를 필드로 가지고 있고, LAZY로 연관관계를 설정하였을 때 , Member만 조회하였을 때는 Team은 아직까지 Proxy객체에 null로 있고, Team의 데이터를 조회했을 때 Proxy객체가 Team 객체를 참조하는걸로 이해했습니다. 그렇다면 Team의 객체가 null로 초기화 되어있다가 조회한 데이터로 초기화되는걸로 이해했습니다. 아니면 그냥 Select 쿼리만 나오고 Team proxy객체는 계속해서 null이고 Team 데이터를 조회 할 때만 select쿼리만 호출되는걸까요..?

List<FMSCompany> contents = companies.getContent();
for (int i = 0; i < contents.size(); i++)
        {
            FMSCompany company = contents.get(i);
            FMSBranch branch = company.getBranches().stream().filter(fmsBranch -> Objects.equals(fmsBranch.getId(), company.getHqBranchId())).findFirst().get();
            System.out.println(branch.getLocation() +", "+ branch.getCompany().getId() +", "+ branch.getBusinessRegistrationNumber() );
        }

}

public class FMSCompany extends AbstractCompany
{

    @JsonManagedReference
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "company", cascade = CascadeType.ALL)
    private List<FMSBranch> branches = new ArrayList<>();

    @JsonManagedReference
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "company", cascade = CascadeType.ALL)
    private List<FMSBranchGarage> garages = new ArrayList<>();

    @JsonIgnore
    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "hqBranchId", foreignKey = @ForeignKey(name = "fk_fms_company__fms_branch__id"))
    private FMSBranch hqBranch;

    @Column(insertable = false, updatable = false, columnDefinition = "BIGINT(20) COMMENT '본사 아이디'")
    private Long hqBranchId;

    // ATTRIBUTENAME: owner -> boss, ownerId -> bossId
    @JsonBackReference
    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.DETACH)
    @JoinColumn(name = "ownerId", foreignKey = @ForeignKey(name = "fk_fms_company__fms_user__id"))
    @ToString.Exclude
    private FMSUser owner;

    @Column(columnDefinition = "TINYINT(1) DEFAULT 1 COMMENT '삭제 여부 (0: 삭제 안 함, 1: 삭제)'")
    private Boolean isDeleted = Boolean.FALSE;

    @Column(columnDefinition = "DATETIME DEFAULT NULL COMMENT '마지막 삭제 일시'")
    private LocalDateTime lastDeletedDateTime;

    // ATTRIBUTENAME: grantedRoles -> roles
    // @formatter:off
    @JsonIgnore
    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.DETACH)
    @ToString.Exclude
    @JoinTable
    (
        name = "fms_company_role",
        indexes =
        {
            @Index(name = "idx_fms_company_id", columnList = "fms_company_id"),
            @Index(name = "idx_role_id", columnList = "role_id"),
        },
        joinColumns = @JoinColumn(name = "fms_company_id", referencedColumnName = "id", foreignKey = @ForeignKey(name = "fk_fms_company_role__fms_company__id")),
        inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id", foreignKey = @ForeignKey(name = "fk_fms_company_role__role__id"))
    )
    private List<Role> grantedRoles;
}
public class FMSBranch extends AbstractEntity
{

    @Column(columnDefinition = "VARCHAR(20) COMMENT '지점 이름'", length = 20)
    private String name;

    @Column(columnDefinition = "VARCHAR(15) COMMENT '사업자등록번호'")
    private String businessRegistrationNumber;

    @Column(columnDefinition = "TEXT COMMENT '주소'")
    private String address;

    @Embedded
    private Location location;

    @Column(columnDefinition = "VARCHAR(20) COMMENT '연락처'")
    private String phone;

    @Column(columnDefinition = "TEXT COMMENT '설명'")
    private String description;
    // @Column(columnDefinition = "VARCHAR(20) COMMENT '조직 유형 (HEADQUARTER: 본점, AGENT_OFFICE: 지점)'")
    // @Enumerated(value = EnumType.STRING)
    // private Organization organization;
    //
    // @Column(columnDefinition = "VARCHAR(20) COMMENT '지점 상태 (NORMAL: 정상, BLOCKED: 정지)'")
    // @Enumerated(value = EnumType.STRING)
    // private ServiceStatus status;

    @Column(columnDefinition = "TINYINT(2) COMMENT '조직 유형 (0 - HEADQUARTER: 본점, 1 - AGENT_OFFICE: 지점)'")
    @Convert(converter = OrganizationConverter.class)
    private Organization organization;

    @Column(columnDefinition = "TINYINT(2) COMMENT '상태 (0 - BLOCKED: 정지, 1 - NORMAL: 정상)'")
    @Convert(converter = ServiceStatusConverter.class)
    private ServiceStatus status;

    @JsonBackReference
    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.DETACH)
    @JoinColumn(name = "ownerId", foreignKey = @ForeignKey(name = "fk_fms_branch__fms_user__id"))
    @ToString.Exclude
    @EqualsAndHashCode.Exclude
    private FMSUser owner;

    @Column(columnDefinition = "BIGINT(20) COMMENT '소유자 아이디'", insertable = false, updatable = false)
    private Long ownerId;

    @JsonBackReference
    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.DETACH)
    @JoinColumn(name = "companyId", foreignKey = @ForeignKey(name = "fk_fms_branch__fms_company__id"))
    @ToString.Exclude
    @EqualsAndHashCode.Exclude
    private FMSCompany company;

    @Column(columnDefinition = "BIGINT(20) COMMENT '업체 아이디'", insertable = false, updatable = false)
    private Long companyId;

    @Column(columnDefinition = "TINYINT(1) DEFAULT 1 COMMENT '삭제 여부 (0: 삭제 안 함, 1: 삭제)'")
    private Boolean isDeleted = Boolean.FALSE;

    @Column(columnDefinition = "DATETIME DEFAULT NULL COMMENT '마지막 삭제 일시'")
    private LocalDateTime lastDeletedDateTime;

    @JsonManagedReference
    @OneToOne(fetch = FetchType.LAZY, mappedBy = "fmsBranch", cascade = CascadeType.ALL)
    private FMSBranchPushStatus fmsBranchPushStatus;

    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    @Transient
    private String companyName;

    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    @Transient
    private CountInBranchDTO count;

    @JsonManagedReference
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "branch", cascade = CascadeType.ALL)
    private List<FMSBranchGarage> garages = new ArrayList<>();
}

 

FMSBranch의 데이터를 조회를 했음에도 불구하고 FMSBranch Proxy는 계속해서 null로 초기화 되어있습니다..

JPA java

답변 1

0

김영한

안녕하세요. epfvkdlxj1님^^

proxy 객체의 필드는 초기화와 무관하게, 항상 null입니다. 메서드를 호출해서 target을 조회하는 것 뿐입니다.

관련해서 프록시 부분을 다시 복습하시면 이해가 되실거에요.

감사합니다.

0

epfvkdlxj1

넵! 감사합니다. 한번 더 복습을 해야겠습니다. 답변 감사합니다 :) 

벌크연산에서 member.getAge 호출 시 영속성 컨텍스트에서 데이터를 가져오는건가요?

0

25

2

inheritance startegy 선택시 고려사항

0

22

1

Entity 동등성 비교

0

18

1

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

0

46

1

H2데이터베이스 파일 생성

0

56

2

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

0

52

2

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

0

52

1

JPQL 메소드와 락

0

55

1

Delivery @OneToOne

0

60

1

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

0

93

2

UnsupportedOperationException 발생

0

86

3

H2 Database 연결이 안됩니다.

0

92

2

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

0

85

2

h2데이터베이스 실행오류

0

107

2

persistence.xml

0

106

2

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

0

80

1

영속성 컨텍스트

0

66

1

JPA 프록시

0

95

1

Native Query와 MyBatis

0

68

1

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

0

87

1

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

0

114

3

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

0

94

3

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

0

108

2

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

0

144

1