개발 지식/JPA

[JPA] Entity 클래스의 @NoArgsConstructor(access = AccessLevel.PROTECTED)

서하빈 2023. 11. 7. 16:52

Entity가 기본생성자를 필요로 하는 이유

- JPA는 DB 값(레코드)을 자바 객체로 매핑할 때 Reflection을 이용한다.

- Reflection이란 구체적인 클래스 타입을 알지 못해도 그 클래스의 메서드, 타입, 변수들에 접근할 수 있도록 해주는 Java API이다.

- JPA에서는 자바 객체로 매핑할 때 기본생성자를 통해 먼저 객체를 만들고나서, Reflection을 통해 필드 값을 주입한다.

- 따라서 Entity에는 기본생성자가 필요하고 기본생성자가 없다면 예외가 발생한다.(InstantiationException)

 

 

Proxy 객체란?

- 상속을 이용해 특정 객체를 한 번 감싸 이전, 이후에 특정 로직을 추가하도록 하는 개념이다.

- JPA의 fetch 타입을 LAZY(지연로딩)으로 할 경우, Proxy로 해당 객체를 한 번 감싸기 때문에 기본생성자를 protected, default, public 중 하나로 지정해야 한다.

- 객체의 무분별한 생성을 막기 위해서(대체로 프록시에서만 객체를 생성하도록 한다.) 기본생성자 타입을 protected로 하는 것이 좋다.

 

 

결론

- JPA는 DB 값을 자바 객체로 매핑할 때 기본생성자로 객체를 생성한 후 필드 값을 주입하는 Reflection 기술을 사용하고 연관관계 매핑에서 fetch 타입을 LAZY로 설정한 경우 프록시 객체를 사용하는데 프록시 객체를 생성할 때 기본생성자가 필요하기 때문에 @NoArgsConstructor(access = AccessLevel.PROTECTED) 설정을 하는 것이 좋다.(접근제어자 설정은 무분별한 엔티티 객체 생성을 막기 위함)

- JPA에서 사용되는 Reflection 기술과 proxy 객체 사용과 같은 자바의 동적 프로그래밍에서 기본생성자가 필요하기 때문에 엔티티에는 반드시 기본생성자가 필요하다!

 

 

참고 자료

https://erjuer.tistory.com/106

 

[JPA] Entity Class의 @NoargsConstructor (access = AccessLevel.PROTECTED)

실무에서 JPA를 활용하다보면 Entity 생성시 @NoargsConstructor (access = AccessLevel.PROTECTED) 이라는 Annotation을 붙여서 개발을 하게 된다. 이에 조금 더 정확히 이해하고자 이번 블로그 글로 언급하고자 한

erjuer.tistory.com

 

https://jh-labs.tistory.com/152

 

[JPA] Entity와 기본생성자, Proxy

Entity가 기본생성자를 필요로 하는 이유 - JPA는 DB 값을 자바 객체로 직렬화할 때 Reflection을 이용함 - Reflection이란 구체적인 클래스 타입을 알지 못해도 그 클래스의 메소드, 타입, 변수들에 접근

jh-labs.tistory.com