흔히 스프링에서 JPA를 사용하다 보면 엔티티에 인자가 없는 생성자를 사용하라고 강제할 때가 있습니다.
해당 클래스를 인스턴스화 할 수 있도록 모든 인자를 받는 생성자를 선언했지만, 컴파일러는 에러를 뱉는군요...
왜 그럴까요?
그 이유는 바로 JPA가 기본 생성자를 필요로 하기 때문입니다.
정확히는 JPA가 Reflection
을 사용해 엔티티 클래스의 인스턴스를 생성할 때 기본 생성자가 사용됩니다.
Reflection 이란 무엇일까요??
Reflection is a feature in the Java programming language. It allows an executing Java program to examine or "introspect" upon itself, and manipulate internal properties of the program. For example, it's possible for a Java class to obtain the names of all its members and display them.
Oracle Technical - Using Java Reflection
reflection은 자바 프로그래밍 언어의 특징입니다. 실행 중인 자바 프로그램이 스스로를 조사하거나 "내성"할 수 있으며, 프로그램의 내부 속성을 조작할 수 있습니다. 예를 들어, 자바 클래스는 모든 구성원의 이름을 획득하여 표시할 수 있습니다.
파파고 번역
Reflection
이란 자바 언어에서 제공하는 기능 중 하나로, 클래스의 내부 정보를 알 수 있게 도와주는 API 입니다.
어플리케이션 실행 중에 클래스의 인스턴스 변수, 메서드 등의 클래스 구조를 파악할 수 있게 도와주죠.
즉, JPA는 동적으로 엔티티 클래스의 인스턴스를 생성할때 Reflection API를 사용해서 객체를 생성합니다. 그리고 이 Reflection API가 생성할 인스턴스의 클래스 정보를 얻기 얻기 위해서 public
혹은 protected
으로 선언된 기본 생성자가 필요한 것입니다.
Dolphin.java
Ocean.java
ApplicationTest.java
보시다시피 Ocean
의 프록시에 접근하는 모습을 볼 수 있습니다.
fetch 설정을 지연로딩으로 설정했기 때문이죠!!
그리고 저 Ocean
의 프록시 객체를 생성할 때, JPA가 Ocean
엔티티의 기본 생성자를 이용해 프록시 객체를 생성합니다.
그런데 컴파일 오류가 난 이유는 무엇일까요?
The JPA specification requires that all persistent classes have a no-arg constructor. This constructor may be public or protected. Because the compiler automatically creates a default no-arg constructor when no other constructor is defined, only classes that define constructors must also include a no-arg constructor.
Apache - Chapter 4. Entity, Part 2. Java Persistence API
JPA 규격에서는 모든 영구 클래스에 no-arg 생성자가 있어야 합니다. 이 생성자는 공개적이거나 보호될 수 있습니다. 컴파일러는 다른 생성자가 정의되지 않은 경우 기본 no-arg 생성자를 자동으로 생성하므로 생성자를 정의하는 클래스에만 no-arg 생성자가 포함되어야 합니다.
파파고 번역
바로 제가 기본 생성자가 아닌 별도의 생성자를 정의했기 때문입니다.
별도로 생성자를 정의하지 않았다면, 자바가 기본 생성자를 생성했겠지만, 제가 생성한 기본생성자 때문에 그렇기는 못하고,
기본 생성자가 필요하지만, 없기 때문에 컴파일 에러를 일으킨 것이죠
Baeldung - Need for Default Constructor in JPA Entities
Apache - Chapter 4. Entity, Part 2. Java Persistence API
Oracle Technical - Using Java Reflection
[Tecoble - Reflection API 간단히 알아보자.](Reflection API 간단히 알아보자.)