final 클래스는 왜 JPA 엔티티가 될 수 없을까?

Yeseong31·2023년 9월 11일
0

final 클래스, final 필드를 포함하는 클래스는 JPA의 엔티티가 될 수 없다.
이는 JPA가 내부적으로 지연 로딩(Lazy Loading)을 사용하기 때문이다.




지연 로딩(Lazy Loading)

✏️ 지연 로딩(Lazy Loading)은 연관된 엔티티를 실제로 사용하는 시점에 조회한다.

  • JPA는 지연 로딩으로 데이터를 조회하는 데 프록시 객체를 생성하여 사용한다.
  • 연관된 엔티티를 프록시로 먼저 조회한 다음, 프록시를 실제 사용할 때 초기화를 하면서 DB를 조회한다.
    • 이때 조회 대상이 이미 영속성 컨텍스트에 있다면, 원본 객체를 조회한다.



프록시(Proxy)

✏️ 지연 로딩을 사용하려면 데이터베이스 조회를 지연시킬 수 있는 가짜 객체가 필요하다.

  • 프록시는 쉽게 말하면 “가짜 객체”이다.
  • 프록시는 실제 클래스를 상속하여 만들어지고, 내부에 실제 객체의 참조를 가지고 있다.

지금까지의 내용을 정리해 보자.
JPA지연 로딩을 사용하고, 지연 로딩은 내부적으로 프록시를 사용한다.
프록시 객체실제 객체를 상속하여 만들어진다.




final 키워드

  • final 키워드는 어떤 곳에 사용되느냐에 따라 그 의미가 달라진다.
  • 변수(필드)에 사용되면 해당 변수를 수정할 수 없음을 의미한다.
  • 메서드에 사용되면 오버라이딩(overriding)이 제한됨을 의미한다.
  • 클래스에 사용되면 상속이 불가능함을 의미한다.



final이 붙을 때 JPA 엔티티가 될 수 없는 이유

final 클래스

  • final이 붙은 클래스는 상속될 수 없다.
  • 이는 JPA에서 해당 클래스를 상속한 프록시 객체를 만들 수 없다는 것을 말한다.
  • 따라서 JPA 엔티티로 사용하고 싶은 클래스에는 final이 붙으면 안 된다.

final 필드를 포함하는 클래스

  • final 필드가 포함된 클래스 역시 JPA 엔티티가 될 수 없다.
  • 이는 JPA가 프록시 객체를 생성할 때 리플렉션이라는 기술을 사용하기 때문이다.

리플렉션(Reflection)

JVM은 클래스 정보를 클래스 로더를 통해 읽어와서 JVM 메모리에 저장한다.
그렇게 저장된 클래스 정보는 마치 “거울에 투영된 모습”과 닮아 있어 리플렉션이라 부른다.
리플렉션을 사용하면 생성자, 메서드, 필드 등의 클래스 정보를 자세히 알아낼 수 있다.

  • 리플렉션으로 객체를 생성하기 위해서는 그 객체가 기본 생성자를 가지고 있어야 한다.
  • 이렇게 만들어진 프록시 객체의 필드들을 초기화하기 위해서는 setter를 사용해야 한다.
  • 하지만 final 필드는 setter를 통해 초기화 및 수정을 할 수 없다.
  • 따라서 JPA 엔티티로 사용하고 싶은 클래스에는 필드에도 final이 붙으면 안 된다.
profile
역시 개발자는 알아야 할 게 많다.

0개의 댓글

관련 채용 정보