기본 생성자를 추가할때, AccessLevel을 PRIVATE이 아닌 PROTECTED를 하는 이유는?
2024. 1. 12. 09:09ㆍspring/심화
@NoArgsConstructor(access = AccessLevel.PROTECTED)
기본 생성자를 추가할때, AccessLevel을 PRIVATE이 아닌 PROTECTED를 하는 이유는?
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED) // 기본생성자를 생성하되, 접근수준을 protected로 하자!
@Entity
public class Product extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String productNumber;
}
@NoArgsConstructor(access = AccessLevel.PROTECTED)
= 아무런 매개변수가 없는 생성자를 생성하되 다른 패키지에 소속된 클래스는 접근을 불허한다.
즉, 아래와 같은 코드를 생성해준다는 뜻이다.
protected class Product() {
}
- 접근 권한을 private이 아니라, protected를 해야만, 프록시 객체를 생성할 수 있기 때문
그럼 프록시 객체는 뭔데?
- 프록시 : 연관된 객체를 처음부터 DB에서 조회하는 것이 아니라, 내가 사용하는 시점에 DB로부터 조회할 수 있다.
- 프록시 객체 : 지연로딩을 통해, 실제 객체 대신 DB조회를 지연할 수 있는 가짜 객체
public class Post{
@Id
@Column(name = "post_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String content;
private String hashTag;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
public void setUser(User user){
// 기존 user와의 관계를 제거
if (this.user != null) {
this.user.getPostList().remove(this);
}
this.user = user;
user.getPostList().add(this);
}
}
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
@Getter
@Setter
@Entity
public class User{
@Id
@Column(name = "user_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String password;
private String email;
private String name;
private LocalDate birth;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.REMOVE)
private List<Post> postList = new ArrayList<>();
}
Post post = em.find(Post.class, "postId"); // User 프록시 객체를 생성한다.
User user = post.getUser();
System.out.println("게시글 제목 : " + post.getTitle());
위 코드에서는 post.getTitle()를 보면 알 수 있듯, Post의 정보만 출력하고 있다. 즉, 연관관계인 User정보는 필요하지 않음. 따라서, @ManyToOne(fetch = FetchType.LAZY) 와 @OneToMany(fetch = FetchType.LAZY 에서 알 수 있듯, User객체는 필요하지 않기때문에 지연로딩을 권장한다.
- 지연로딩 : 특정한 엔터티가 실제 사용될때까지 DB조회를 지연하는 것
- 지연 로딩 : 연관된 엔티티를 프록시로 조회하고, 프록시를 실제 사용할 때 프록시를 초기화하면서 데이터베이스를 조회한다.
- 즉시 로딩 : 연관된 엔티티를 즉시 조회하고, 하이버네이트는 가능하면 SQL 조인을 사용해서 한 번에 조회한다.
- 지연로딩을 권장.
지연로딩을 사용하려면, 실제 엔터티 객체 대신 DB조회를 지연할 수 있도록 도와주는 가짜 객체가 필요한데 이를 프록시 객체라고 한다.