[Spring/JPA]@Entity에서 final을 사용하면 안되는가?

2022. 4. 2. 19:06

엔티티를 사용하는데에 주의사항이 몇가지 있다.

  • 기본생성자를 필수적으로 가져야 한다.
  • final class, enum, interface, inner class 에서는 사용할 수 없다.
  • 엔티티의 모든 필드들은 final을 사용할 수 없다.

왜 final 키워드를 사용할 수 없을까?

 

lombok 에러가 발생

Order 구현 엔티티에 final을 작성했을 때, 롬복이 정상적으로 동작하지 않는다는 에러가 발생한다. 왜 엔티티에서는 final 구문을 쓸 수 없는 지는 “지연로딩"에 있었다.

💡 지연로딩(”fetchType = LAZY”)이란?
엔티티와 관계(join) 맺고 있는 엔티티에 대한 정보는 즉시 로딩되지 않고, getter 메소드가 호출하는 등의 사용 시점에서 로딩된다.

JPA는 DB에서 데이터를 조회한 후, 엔티티를 생성할 때 지연로딩 전략을 사용한다.

지연 로딩방식을 이용해 DB를 조회하기 위해서는 JPA는 프록시 객체를 생성해야 한다. 프록시 객체란 엔티티를 상속해서 생성된 확장된 클래스이다. final field가 포함된 클래스는 상속될 수 없는 특징을 가지고 있기 때문에(실행 시, 메모리 최상단에 위치하게 된다) 해당 클래스를 확장하여 프록시 객체로 사용할 수 없다.

또한 Entity 클래스는 JPA에 의해 프록시 객체로 확장되어 생성할 때 Replection API를 호출하게 된다.

Reflection api를 통해 객체를 호출하려면 기본 생성자가 반드시 필요한데, 필드들을 초기화하려면 setter 가 이 시점에서 필요하다. 하지만 final class는 setter를 이용하여 초기화할 수 없다. 이러한 이유로 인해 final class는 엔티티가 될 수 없다.

 

*참고*

final 필드를 초기화하기 위해서는 2가지 방법이 있다.

  1. 클래스 로딩시점에서 초기화
  2. 생성자를 이용

 

'programming > Spring' 카테고리의 다른 글

[JPA] ORM, 패러다임의 불일치  (0) 2022.03.12

BELATED ARTICLES

more