- JPA Entity Default Constructor2023년 06월 07일
- starryeye
- 작성자
- 2023.06.07.오후11:57
JPA 의 공식 문서 JSR 338, Java Persistence API 를 보면.. 이런말이 나온다.
2.2 version
즉, 엔티티 클래스는 Default 생성자를 반드시 가져야한다. (생성자의 접근지정자는 public or protected)
물론 표준 스팩일 뿐이므로 JPA 의 구현체 마다 다를 수 있다.
오늘은 이 부분에 대해 알아보자..
JPA 의 Entity 생성 방식
DB 에서 데이터를 읽고 Entity 를 반환해주려면..
JPA Entity 를 동적으로 생성하고 읽어온 데이터를 바인딩해줄 필요가 있다.
그래서, 기본 생성자를 통해 객체를 동적으로 생성하고
Java Reflection 을 이용하여 필드 값을 바인딩 해주는 방식으로 동작한다.
참고>
JPA는 런타임에 어떤 타입의 엔티티를 생성할지 모른다.
따라서, 어떤 타입으로 엔티티를 만들더라도 해당 엔티티를 생성하기 위해 Reflection 을 사용한다.
또한,Java Reflection 은 생성자의 매개변수 정보를 얻지 못한다.그래서, All argument constructor 로는 엔티티를 생성해주지 못하여no argument contructor 으로 생성하는 방식을 채택한 것이다.-> Java Reflection 으로 생성자의 매개변수 정보(파라미터 타입, 파라미터 이름..) 를 얻을 수 있다.
하지만, 그럼에도 Default constructor 생성이 표준인 이유는...
다른 생성자들에서는..
파라미터의 이름과 실제 필드 이름이 매핑되는것을
JPA 입장에서는 보장받을 수 없기 때문에(개발자를 믿지 않음..) 일 것으로 보인다.
따라서, Default Contructor 를 통해 reflection 기술로 동적으로 엔티티를 생성하고
실제 선언된 필드 이름을 보고 값을 채운다.
그런데..
Reflection 은 생성자의 접근 지정자가 private 라도 생성해줄 수 있는데..
JPA 는 public, protected 만 허용한다.
이에 대해서 알아보자..
JPA 의 지연 로딩 방식
JPA 는 Proxy 객체를 바탕으로 Lazy Loading 기술을 지원한다.
지연로딩을 사용하기 위해서는 원본 엔티티의 프록시 객체를 만들 필요가 있는데..
원본 엔티티의 프록시 객체는 원본 엔티티를 상속해서 만들어야한다.
상속한 객체의 생성자는 반드시 부모 객체의 생성자 super 를 호출해야한다.
하지만..
원본 엔티티의 기본 생성자가 private 라면..
해당 엔티티를 상속한 프록시 객체가 원본 엔티티의 기본 생성자를 호출할 수 없게 된다. (런타임 에러)
결론..
JPA 입장에서, 컴파일에는 생성해야할 엔티티의 타입을 모르는채로
런타임에 엔티티 객체를 생성해야하여 Java Reflection 을 사용하였고,
정확하고 단순하게 엔티티를 reflection 을 통해 생성하기 위해
JPA Entity 는 기본 생성자가 필요하고,
Lazy Loading 기술을 지원하기 위해 Proxy 객체를 만들어야하는데
Proxy 객체는 원본 객체를 상속받아야 하므로 private 는 사용될 수 없다.
그래서, 접근 지정자는 public, protected 가 허용된다.
'Spring > DB, Cache 연동' 카테고리의 다른 글
JPA 등록, 기본 키 생성 전략 (0) 2023.06.19 JPA 변경 감지와 플러시 (0) 2023.06.15 JPA Merge, Dirty Check (0) 2023.06.06 Spring Cache Annotation (0) 2023.06.04 Spring Data Redis (0) 2023.06.03 다음글이전글이전 글이 없습니다.댓글