FrameWork/Spring Boot

[Spring Boot] JPA Entity

JiWonSon 2022. 8. 4. 15:35

1.JPA사용 시 Entity 구성

 @Id 

 primary key를 가지는 변수를 선언하는 것을 뜻한다. @GeneratedValue 어노테이션은 해당 Id값을 어떻게 자동으로 생성할 지 전략을 선택할 수 있다.

일반적으로는 @GeneratedValue(Strategt = GenerationType.AUTO)를 사용한다. DB에 맞게 자동으로 생성해주는 역할을 한다.

@ManyToOne

2. Entity에 기본생성자가 필수

- JPA의 Entity는 반드시 파라미터가 없는 기본 생성자를 지녀야 한다.

- 이 기본생성자는 public, protected여야하며, private이면 안된다.

 

2-1. 기본생성자가 필요한 이유

동적으로 객체 생성 시 Reflection API를 활용하기 때문이다.

 

JPA는 DB값을 객체 필드에 주입할 때,  

 

①기본 생성자로 객체를 생성하고

Reflection API를 사용하여 값을 매핑한다. 

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

 단, JPA를 사용하지 않고 JDBC를 사용한다면 기본생성자가 필요하지 않을 수도 있다.

 

i) 기본생성자를 작성하지 않는다면 다음과 같은 예외가 나타난다.

org.hibernate.InstantiationException: No default constructor for entity:  :

 

 

 위 내용을 보면 GET 요청을 통해 repository에서 엔티티 정보를 조회해 인스턴스를 만들 때 기본생성자를 사용한다는 것을 알 수 있다. 디버깅을 해보면 PojoInstantiator의 intantiate()라는 메소드에서 인스턴스를 생성하려다 실패하고 예외가 발생합니다.

 

ii) 기본생성자를 private으로 지정하고 실행하면  다음과 같은 예외가 나타난다.

java.lang.InstantiationException:

 추후에 Lazy Loading 사용 시 Proxy 관련 예외가 발생할 수 있다.

-> JPA가 매핑한 Entity를 조회할 때 hibernate가 생성한 proxy 객체를 사용하여 연관된 데이터를 실제 사용하는 시점에 조회할 수 있는데, proxy 객체는 직접 만든 객체 class를 상속하기 때문에 public 혹은 protected 기본 생성자가 필요하다. 

 

* JPA는 매핑한 Entity를 조회할 때 두가지 방법이 있다.

- 조회 시점에 함께 가져오는 EAGER

- 매핑한 Entity를 사용할 때 조회하는 LAZY

이 때, LAZY(지연로딩)방식을 사용할 경우 임시로 hibernate가 생성한 proxy객체를 생성하고 가리키게 된다.

 

 

 

3. Reflection API?

 

자바에서는 JVM이 실행되면 작성된 자바 코드가 static 영역에 저장된다.

Reflection API는 구체적인 클래스 타입을 알지 못해도 클래스 이름을 통해 static 영역에서 그 클래스의 정보(메서드, 타입, 변수 등등)에 접근할 수 있게 해주는 Java API다.

기본 생성자가 아닌 파라미터가 있는 생성자만 존재한다면 java reflection이 객체를 생성할 수 없음

'FrameWork > Spring Boot' 카테고리의 다른 글

[Spring Boot] SOAP API & REST API  (0) 2021.01.23
[Spring Boot]JPA의 기본 개념  (2) 2021.01.18
[Spring Boot] Spring과 Spring Boot 차이  (0) 2020.12.11