
@NoArgsConstructor(access = AccessLevel.PROTECTED)를 쓰는 이유에 대해서 정리해보려고 한다.
기존 프로젝트에서는 그냥 PROTECTED로 하면 좋다는 이야기만 듣고 진지하게 고민하지 않고 사용했었는데, 졸프에서는 정확한 이유를 가지고 사용해 보고 싶어 정리하게 되었다.
해당 내용에 대해서 찾다보니 지연로딩에 대해서 먼저 알 필요가 있다.
@ManyToOne(fetch = FetchType.LAZY)
연관된 객체를 처음부터 db에서 조회하는 것이 아니라 실제 사용하는 시점에 db로부터 조회하는 것
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Table(name="program_participants")
@AllArgsConstructor
public class ProgramParticipants extends BaseEntity {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "users_id", foreignKey = @ForeignKey(name = "program_participants_fk_users_id"))
private User user;
지연로딩 사용시, 실제 엔티티 객체 대신 db 조회를 지연할 수 있는 가짜 객체가 필요한데, 이를 proxy 객체라고 한다.
연관된 엔티티의 프록시 객체를 생성했다가 해당 프록시 엔티티를 사용할 때, 프록시 엔티티의 멤버 변수는 참조된 실제 엔티티의 메서드를 호출해서 값을 리턴한다. 만약 프록시 엔티티의 멤버변수가 null이면 프록시 초기화 과정을 거쳐야 한다.
프록시 초기화 : 프록시 객체는 실제 엔티티가 사용될 때 db를 조회해서 실제 인티티 객체를 생성해서 참조하는 것
프록시 클래스는 실제 클래스를 상속 받아서 만들어진다.
프록시 객체는 실제 객체에 대한 참조를 보관한다.
프록시 객체의 메서드 호출시, 프록시 객체는 실제 객체의 메서드를 호출한다.
<즉시로딩>
@ManyToOne(fetch = FetchType.EAGER)
객체 호출 시 연관된 엔티티도 함께 조회함
외부 조인 쿼리를 사용
해당 롬복에 대해서 간단히 집고 넘어가보자
@NoArgsConstructor : 파라미터가 없는 기본 생성자를 생성
(access = AccessLevel.PROTECTED) : 접근 제한자를 protected로 설정
=> @NoArgsConstructor(access = AccessLevel.PROTECTED) : 접근 제한자가 protected인 기본 생성자를 생성
그래서 지연로딩이 @NoArgsConstructor(access = AccessLevel.PROTECTED)와 무슨 관계가 있는지 궁금할 것이다.
위에서 엔티티의 연관관계에서 지연로딩을 사용하면 프록시 객체를 통해서 조회한다고 설명했다.
이 프록시 객체를 사용하기 위해서는 JPA 구현체는 실제 엔티티의 기본 생성자를 통해 프록시 객체를 생성하는데, 이 때 접근 권한이 private이면 프록시 객체를 생성할 수 없다.
접근제한자가 private이면 상속한 자식 클래스에서 생성자를 사용할 수 있는 것으로 알고 있는데 프록시 객체는 본 객체를 상속받아서 생성되는 것이 아니라는 건가요? 어떤 식으로 프록시 객체가 생성되는지 궁금합니다!