인프런에서 김영한님의 강의를 들으면서 “JPA의 Entity객체에는 기본 생성자가 있어야 한다” 라는 말을 들은적이 있다.
왜 그런 걸까? 알아보도록 하자.
위의 이유를 알기 위해서는 먼저 java Reflection를 알아야 한다.
구체적인 클래스 타입을 알지 못해도, 그 클래스의 메소드, 타입 변수들에 접근할 수 있도록 해주는 API
예를 들어 다음과 같은 Music 클래스가 있을 때
public class Music {
private String singer;
private String title;
public Music(String singer, String title) {
this.singer = singer;
this.title = title;
}
public Music(){
}
public String getTitle() {
return title;
}
public String getSinger() {
return singer;
}
}
public class Reflection {
public static void main(String[] agrs) {
Object music = new Music("IU", "YOU AND ME")
music.getTitle() // 이 코드를 사용 할 수 없다.
}
}
Music을 Object로 받으면 Music 클래스에 선언된 getter함수들을 사용 할 수 없다.
이렇게 (Object) music이 구체적인 클래스 타입을 알지 못할 때 Music의 메소드를 사용가능 하도록 해주는 기능이 Reflection이다.
public class Main {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Object music = new Music("IU", "YOU AND ME");
//== JAVA Reflection==//
Class c = Music.class;
Method getTitle = c.getMethod("getTitle");
String title = (String) getTitle.invoke(music, null);
System.out.println("title = " + title);
}
}
이 외에도 Reflection API는 아래와 같은 여러 기능을 제공한다
public class Main {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Object music = new Music("IU", "YOU AND ME");
//== JAVA Reflection==//
Class c = Music.class;
Constructor constructor = c.getDeclaredConstructor(String.class, String.class);
System.out.println("constructor = " + constructor); // public Music(java.lang.String,java.lang.String)출력
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
System.out.println("field = " + field.getName());
} // singer, title 출력
}
}
다시 원론으로 돌아가면,
Java Reflection API를 사용하면 해당 클래스의 매서드, 맴버 변수, 변수 타입 등을 알 수 있다.
하지만 가져올 수 없는 정보 중 하나가 생성자의 인자 정보들이다.
따라서 기본 생성자가 없다면 java Reflection은 해당 객체를 생성 할 수 없기 때문에 JPA의 Entity에는 기본 생성자가 필요하다.