2021. 3. 11. 11:23ㆍJPA
postman으로 테스트 중... 아래와 같은 에러가 발생하였다.
org.hibernate.InstantiationException: No default constructor for entity
Entity 클래스를 반환해주는 과정에서 클래스의 JSON Serialize 오류가 났는데...
default Constructor(기본 생성자)를 추가해주면 간단하게 해결이 가능하다.
import javax.persistence.*;
import java.io.Serializable;
@Entity
public class User implements Serializable {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column private Long id;
@Column private String username;
@Column private String password;
// [S] ====================== 생성자를 추가해주자. ======================
protected User() {
}
// [E] ====================== 생성자를 추가해주자. ======================
}
그러면 왜 인자가 없는 생성자를 추가해주면 해결되는가?
(읽기 전... 이 문제는 Java 리플렉션이랑 관련이 있다. 리플렉션 개념이 필요하다면 클릭 !)
JPA 2.0 스펙에는 다음과 같이 명시된 문장이 있다.
엔티티는 반드시 파라미터가 없는 (no-arg) public 또는 protected 생성자가 있어야 한다. |
JPA 스펙에서 파라미터가 없는 생성자는 필수로 있어야 한다고 알려주고 있다. 이유는 무엇일까?
먼저 Java 는 기본 생성자를 사용하지 않아도 자동으로 생성해준다.
하지만 파라미터가 존재하는 생성자를 작성하였을 경우, 기본 생성자를 자동으로 생성해주지 않는다.
JPA는 리플렉션을 하기 위해 해당 Entity 객체의 default Constructor를 이용하여 객체를 생성한다.
그리고 Reflection을 이용해 값을 매핑한다.
그런데 Reflection이 가져올 수 없는 정보 중 하나가 Constructor의 인자 정보들이다. 그래서 default Constructor가 반드시 있어야 객체를 생성할 수 있는 것이다. default Constructor로 객체를 생성만 하면 필드 값 등은 Reflection API로 넣어줄 수 있다.
기본 생성자 없이 파라미터가 있는 생성자만 존재한다면... Reflection 이 객체를 생성할 수 없게 되어 위와 같은 예외가 발생하게 된다.
마지막으로 기본 생성자는 protected 타입으로 선언된 이유는 무엇일까?
protected인 이유는 JPA에서 Entity 클래스를 생성할 수 있도록 허용 (리플렉션) 하지만, 코드상에서 개발자들의 무분별한 Entity 생성을 못하게 막도록 하기 위함이다. (new 키워드 금지) |
'JPA' 카테고리의 다른 글
[JPA] 엔티티 설계시 주의사항 (0) | 2021.03.22 |
---|