JPA Entity , Protected 설정 이유

defaultprotected 차이 요약

접근 제어자
같은 패키지
서브클래스 (다른 패키지)
외부 클래스

default

✅ 가능

❌ 불가능

❌ 불가능

protected

✅ 가능

✅ 가능

❌ 불가능

즉, protected다른 패키지의 서브클래스에서도 접근 가능합니다. default는 오직 같은 패키지에서만 접근이 가능합니다.


🧩 JPA에서 protected를 선호하는 진짜 이유

1. JPA가 프록시를 생성할 수 있어야 함

  • JPA는 엔티티를 프록시로 감싸거나, 서브클래스를 만들어 동작시킴

  • 프록시 클래스는 실제 엔티티를 상속하게 되는데,

  • 이때 기본 생성자가 protected이면 상속한 프록시 클래스에서 접근 가능

  • 하지만 default는 프록시가 다른 패키지에 있으면 접근이 불가능함 ❌

👉 그래서 JPA에서는 protected 생성자를 써야 프록시에서 접근 가능


📌 요약

질문
답변

default로도 외부에서 객체 생성 막을 수 있지 않나요?

맞아요. 같은 패키지 외부에서는 생성 막을 수 있어요.

그럼에도 왜 protected를 쓰나요?

JPA가 프록시 객체를 생성할 때, 다른 패키지의 서브클래스로 생성하므로 protected 접근이 필요합니다.

결론

JPA가 내부적으로 리플렉션 + 프록시 상속을 사용하는 구조 때문에 protected 생성자가 가장 안전하고 호환성 있는 선택입니다.

@Entity
public class Member {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    protected Member() {
        // JPA용 기본 생성자
    }

    public Member(String name) {
        this.name = name;
    }
}
// 예시: Hibernate 내부에서 생성하는 가상의 프록시 클래스
public class Member_$HibernateProxy$ extends Member {

    public Member_$HibernateProxy$() {
        // 여기서 부모 클래스(Member)의 생성자 호출 필요
        super();  // 이게 되려면 Member()가 protected 또는 public이어야 함
    }

    @Override
    public String getName() {
        // 프록시 구현: DB에서 지연로딩
        initializeIfNeeded();
        return super.getName();
    }
}

Last updated