✏️ [JPA] @Entity에서 final을 사용해도 될까?

박상민·2024년 1월 20일
0

JPA

목록 보기
24/24
post-thumbnail

결론부터 말하자면 사용할 수 없다.

엔티티를 사용하는데에는 주의사항이 있다.
1. 기본 생성자를 필수적으로 가져야 한다.
2. final class, enum, interface, inner class 에서는 사용할 수 없다.
3. 엔티티의 모든 필드들은 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가지 방법이 있다.

  • 클래스 로딩시점에서 초기화
  • 생성자를 이용
profile
스프링 백엔드를 공부중인 대학생입니다!

0개의 댓글