• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

하이버네이트 프록시 참조 가능

20.10.10 12:41 작성 조회수 143

1

https://www.inflearn.com/questions/53733

우선 위의 글을 읽고 왔습니다.

트랜잭션을 종료하지 않은 상태에서 em을 닫았기 때문에 아직 트랜잭션이 살아있어서 값이 잘 불러와진다고 하셨습니다.

제 build.gradle의 하이버네이트 버전은 다음과 같이 설정되어있습니다. 

그리고 제가 다음과 같이 코드를 작성했습니다.

그런데도 여전히 값이 잘 불러와집니다. 이 부분은 어떻게 이해해야 하나요?(하이버네이트 버전을 5.4.0으로 해도 값이 잘 참조가 되더라구요.)

답변 3

·

답변을 작성해보세요.

2

안녕하세요. DolphaGo님 좋은 질문입니다.

아마 코드 상위에 해당 엔티티를 저장했거나, 또는 이미 한번 조회해서 그럴꺼에요^^

영속성 컨텍스트에 이미 영속상태로 관리되고 있는 엔티티를 프록시로 조회하면, 프록시로 반환할 이유가 없기 때문에(+영속성 컨텍스트의 동일성 보장) 기존 영속성 컨텍스트에서 관리중인 엔티티를 반환해줍니다.

조회한 프록시 객체를 다음과 같이 출력해보시면

System.out.println("ref = " + ref.getClass());

class hellojpa.Member -> 이런식으로 해당 엔티티 클래스 명이 정확하면 기존에 관리되면 엔티티가 조회된 것이고,

class hellojpa.Member$HibernateProxy$VYWPiECl -> 이런식으로 프록시 클래스가 사용되면 실제 프록시를 통해서 조회된 것입니다.

감사합니다.

1

ㅎㅎㅎ 이렇게 예외를 반기는 분이 있다니 ㅎㅎㅎ

즐거운 하루 되세요.

1

DolphaGo님의 프로필

DolphaGo

질문자

2020.10.10

정말 감사합니다 ㅠㅠㅠㅠ
그러게요. 항상 JPA는 프록시든 실제 엔티티든 영속성 컨텍스트가 관리를 하면 타입을 일치시켜준다는 사실을 잠깐 잊고 있었네요.

그래서 말씀하신것처럼 프록시가 아닌 실제 엔티티를 반환하고 있었습니다. 영속성 컨텍스트를 다 비워주고 getReference()를 호출하여 해결했습니다. 데이터 저장과 참조를 Main에서 같이 실험해서 그랬네요. 실제 개발을 할 땐 LazyInitializationException이 왜 발생하는 것인지 몰랐어서 답답했었는데, 이번 강의를 두번 세번 들으면서 프록시에 대한 개념을 잘 잡게 되었습니다. 정말 감사합니다..

제가 그토록 원하던 LazyInitializationException을 봐서 기분이 너무 좋네요 ㅎㅎ..

휴일에도 답변해주셔서 정말 감사합니다.^^