Yebali

Spring JPA에 기본 생성자가 필요한 이유 본문

Spring

Spring JPA에 기본 생성자가 필요한 이유

예발이 2021. 10. 31. 23:26

인프런에서 김영한 님의 강의를 들으면서 “JPA의 Entity객체에는 기본 생성자가 있어야 한다”라는 말을 들은 적이 있다.

왜 그런건지 알아보자.

 

java Reflection

위의 이유를 알기 위해서는 먼저 java Reflection를 알아야 한다.

 

java Reflection이란?

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

 

예를 들면

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;
    }
}

위와 같은 Music 클래스가 있을 때,

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이다.

 

Java 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는 아래와 같은 여러 기능을 제공한다.

  • getDeclaredConstructor() : 인자가 없는 생성자를 가져온다.
  • getDeclaredConstructor(param) : Param에 인자(타입)를 넣으면 그 타입과 일치하는 생성자를 가져온다.
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 출력
    }
}

 

JPA에서 No-args가 필요한 이유

다시 원론으로 돌아가서,
Java Reflection API를 사용하면 해당 클래스의 매서드, 맴버 변수, 변수 타입 등을 알 수 있다.

하지만 가져올 수 없는 정보 중 하나가 생성자의 인자 정보들이다.

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

'Spring' 카테고리의 다른 글

QueryDSL in Kotlin  (0) 2021.10.31
Spring JPA의 Cache  (0) 2021.10.31
Spring JPA의 @OneToOne 관계와 지연로딩  (0) 2021.10.11
Spring JPA Entity에 기본 생성자가 필요한 이유  (0) 2021.10.11
Spring Data JPA의 페이징과 정렬  (0) 2021.10.11