@Getter
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class PostComment extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id")
private Post post;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_comment_id")
private PostComment parentComment;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
public String content;
@Builder
public PostComment(Post post, User user, String content) {
this.post = post;
this.user = user;
this.content = content;
}
}
@NoArgsConstructor(access = AccessLevel.PROTECTED) 쓰면
Protected 기본생성자가 만들어집니다.
protected PostComment() {}
왜 접근 권한을 Public이 아닌 Protected로 하였을까?
JPA가 Proxy 객체를 생성할 때 기본생성자가 필요합니다. 그러나 저는 기본생성자로 엔티티를 생성할 일이 없습니다. builder를 통해서만 엔티티를 생성합니다. 무분별한 기본생성자 사용을 막기 위해 Protected로 제한하는 것입니다.
왜 접근 권한을 Private이 아닌 Protected로 하였을까?
Entity의 Proxy 조회때문이다.
정확히는 엔티티의 연관 관계에서 지연 로딩의 경우에는 실제 엔티티가 아닌 프록시 객체를 통해서 조회를 한다.
프록시 객체를 사용하기 위해서 JPA 구현체는, 실제 엔티티의 기본 생성자를 통해 프록시 객체를 생성하는데, 이 때 접근 권한이 private이면 프록시 객체를 생성할 수 없는 것이다.
이 때 즉시로딩으로 구현하게 되거나 엔티티가 영속성 컨텐츠에 있을시, 접근 권한과 상관없이 프록시 객체가 아닌 실제 엔티티를 생성하므로 문제가 생기지 않는다
'스프링' 카테고리의 다른 글
HTTP 메소드 PUT, FATCH 차이점(멱등성) (0) | 2024.04.11 |
---|---|
Id로 연관관계 짓기(엔티티로 연관관계x) (0) | 2024.04.09 |
Intellij에서 gradle 버전이 안 보일 때 해결법 (0) | 2024.04.06 |
mysql, gradle 종속성 관리 변경된 점 (0) | 2024.01.31 |
[인가 설정 리팩토링] Security Config -> @PreAuthorize (0) | 2024.01.25 |