
JPA는 엔티티를 DB로부터 가져온다.
정확히는DB에서 조회한 데이터를 기반으로 엔티티 객체를 생성하거나 재사용한다.
그렇다면 JPA가 DB로부터 값을 가져올 때마다 인스턴스를 생성할 수 있는가?
JPA는 트랜잭션 안에서 동일한 엔티티는 영속성 컨텍스트 (Persistence Context)에 보관하고, 이미 관리 중인 엔티티가 있으면 새로 생성하지 않고 재사용하기 때문이다.
리플렉션: 런타임에 클래스의 정보를 보고, 조작할 수 있는 기능
즉, JPA가 DB에서 값을 가져와서 사용할 수 있는 비어있는 (파라미터가 없는) 생성자를 필요로 하게 된다.
protected Member() {
...
}
@NoArgsConstructor
그러나 애노테이션의 기본 접근 제한자로 인해서 발생할 수 있는 문제가 존재한다.
@NoArgsConstructor 애노테이션의 기본 접근 제한자는 public이다.
여기서 어떤 문제가 발생할 수 있을까?
비어있는 생성자를 만드는 것은 JPA가 사용할 수 있는 공간을 할당해주기 위함이다.
그런데 생성자의 접근 제한자를 public으로 생성한다면?
new Member() 등을 호출 가능!@NoArgsConstructor(access = AccessLevel.PROTECTED) 를 이용한다.
접근 제한자를 protected로 설정하여, 외부에서의 잘못된 생성 호출을 막고, JPA가 비어있는 생성자에 DB에서 가져온 값을 안전하게 주입할 수 있도록 한다.