JPA Entity 생성자에 관하여

YEON·2022년 4월 10일
8

JPA

목록 보기
5/5

JPA Entity 생성자에 대하여

JPA의 Entity는 반드시 파라미터가 없는 기본 생성자를 지녀야 한다.
그리고 그 기본 생성자는 public, protected 이어야하고 private 으로 선언해서는 안된다.



1. 기본 생성자가 필요한 이유

Spring Data JPA 에서 Entity에 기본 생성자가 필요한 이유는 동적으로 객체 생성 시 Reflection API를 활용하기 때문이다.

JPA는 DB 값을 객체 필드에 주입할 때 기본 생성자로 객체를 생성한 후 Reflection API를 사용하여 값을 매핑한다.

때문에 기본 생성자가 없다면 Reflection은 해당 객체를 생성 할 수 없기 때문에 JPA의 Entity에는 기본 생성자가 필요하다.



✔︎ java Reflection API 와 관련하여

Reflection API란?

자바에서는 JVM이 실행되면 작성된 자바 코드가 static 영역에 저장된다.

Reflection API는 이 정보를 활용하여 구체적인 클래스 타입을 알지 못해도 클래스 이름을 통해 static 영역에서 그 클래스의 정보(메서드, 타입, 변수 등등)에 접근할 수 있게 해준다.

다만 Reflection API가 생성자의 인자 정보는 가져올 수 없다.
때문에 기본 생성자가 있어야 객체를 생성할 수 있고 생성된 객체를 통해서 Reflection API는 필드 값 등을 넣어줄 수 있다.



2. private 으로 선언하면 안되는 이유

JPA가 매핑한 Entity를 조회할 때 hibernate가 생성한 proxy 객체를 사용하여 연관된 데이터를 실제 사용하는 시점에 조회할 수 있는데,

proxy 객체직접 만든 객체 class를 상속하기 때문에 public 혹은 protected 기본 생성자가 필요하다. (private로 생성자를 만들게 되면 파생 클래스로부터의 상속 형태가 접근 불가가 되어버리기 때문에 제약이 생기게 된다)



✔︎ Proxy 객체와 관련하여

proxy 객체란?

JPA는 매핑한 Entity를 조회할 때 두 가지 전략을 사용한다.
조회 시점에 함께 가져오는 EAGER와 매핑한 Entity를 사용할 때 조회하는 LAZY가 있다.
그리고 이때 지연로딩(LAZY)을 사용할 경우 임시로 hibernate가 생성한 proxy 객체를 생성하고 가리키게 된다.

그럼 proxy 객체랑 생성자랑 무슨 상관일까?
proxy 객체는 직접 만든 class 를 상속하기 때문에 public, protected 기본 생성자를 필요로 하게 된다. 결국 만약 public, protected 생성자가 없다면 proxy 객체를 사용할 수 없게 되는 것이다.



관련하여 발생한 오류

기본 생성자를 private 으로 선언하였을 때 생길 수 있는 오류 (JpaSystemException) 이다.
오류 내역을 보면 친절하게 domain.User 의 Private 생성자는 런타임시 작동할 수 없다. 라고 나와있다.



정리

Entity 는 동적으로 객체 생성 시 java의 Reflection API를 활용하기 때문에 기본 생성자가 필요하며,
Entity 를 조회하기 위해 생성되는 proxy 객체는 직접 만든 객체 class를 상속하기 때문에 public이나 protected 기본 생성자를 선언해야한다.






[참조]
https://hyeonic.tistory.com/191
https://tecoble.techcourse.co.kr/post/2020-07-16-reflection-api/
https://velog.io/@yebali/Spring-JPA에-기본-생성자가-필요한-이유
https://wbluke.tistory.com/6

profile
- 👩🏻‍💻

3개의 댓글

comment-user-thumbnail
2022년 8월 9일

이해하기 쉽게 정리해주셔서 감사합니다!🤩

1개의 답글
comment-user-thumbnail
2023년 10월 9일

깔끔한 정리 감사합니다.

답글 달기