JPA 용어정리(1)-환경설정

lilseongwon·2022년 8월 22일
2
post-thumbnail

이 포스팅 시리즈는 인프런에서 김영한님의 JPA활용 강의를 듣고서
궁금한 점과 중요하다고 생각하는 부분을 정리한 것입니다.

1. @Repository어노테이션은 꼭 필요할까?🤨


김영한님의 강의에서 Repository 클래스를 만들 때 @Repository 어노테이션을 사용하는 것을 보고, "꼭 @Repository어노테이션을 붙여야 할까?" 라는 생각이 들었다.

public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByAccountId(String accountId);
}

평소 프로젝트에서 사용하는 Repository 인터페이스는 JpaRepository를 상속하기에 이를 뜯어보면

@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {

이런 코드가 나온다. 여기서 @NoRepositoryBean은 실제 사용되는 Repository가 아님을 표시하는 것이다.

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(JpaRepositoriesRegistrar.class)
public @interface EnableJpaRepositories

SpringBoot에서는 @EnableJpaRepositories 어노테이션이 자동 설정 되어 있는데,
@Import(JpaRepositoriesRegistrar.class) 가 실제 JpaRepository를 상속받은 Repository 인터페이스를 빈으로 등록해준다.


2. 영속성 컨텍스트(EntityManager)🕋

@repository
public class MemberRepository {

    @PersistenceContext
    private EntityManager em;
    

repository 클래스에 엔티티 매니저라는 개념이 나와서 정리해보겠다.

영속성 컨텍스트는 엔티티를 영구저장하는 환경이고, 어플리케이션이 테이터베이스에서 꺼내온 객체를 보관하는 역할을 한다.

persist 메소드는 엔티티 매니저를 이용해서 회원 엔티티를 영속성 컨텍스트(Persistance Entity)에 저장한다.

참고로 @PersistenceContext는 영속성 컨텍스트를 주입하는 표준 애노테이션이다.

하지만 save가 아니라 persist 인 이유는 DB가 아닌 영속성 컨텍스트에 저장되었기 때문이다. 굳이 영속성 컨텍스트를 거치는 이유 중 하나가 영속된 엔티티의 동일성 보장이다.

영속성 컨텍스트에서 객체를 관리하기 때문에,객체를 여러번 조회하더라도 동일성을 보장한다.
"영속성 컨텍스트에서 식별자가 같으면 같은 엔티티"라는 것이다.

이는 정말 큰 차이인게, 데이터베이스의 트랜잭션 격리 레벨
을 REPEATABLE READ(반복 가능한 읽기)로 할 필요가 없어진다.

트랜잭션과 쿼리🧭

엔티티 매니저를 통해 영속성 컨텍스트에 접근할 수 있다.

하지만 영속 상태가 된다고해서 바로 DB에 쿼리가 날라가는 것이 아니다.

@Autowired MemberRepository memberRepository;

 @Test
 @Transactional
 public void testMember() throws Exception {

     //given
     Member member = new Member();
     member.setUsername("memberA");

     //when
     Long savedId = memberRepository.save(member);
     Member findMember = memberRepository.find(savedId);

DB에는 이후에 커밋해야 저장된다. 그렇기 때문에 "엔티티 매니저를 통한 모든 데이터 변경은 트랜잭션 안에서 이뤄진다"는 것이다.

커맨드와 쿼리 분리🚧

강의 도중에 "커맨드와 쿼리를 분리하는 것이 좋다"고 해서 이를 찾아보았다.

이 메서드를 호출 했을 때, 내부에서 변경(사이드 이펙트)가 일어나는 메서드인지, 아니면 내부에서 변경이 전혀 일어나지 않는 메서드인지 명확히 분리하면 데이터 변경 관련 이슈가 발생했을 때, 변경이 일어나는 메서드만 찾아보면 된다.

정말 크리티컬한 이슈들은 대부분 데이터를 변경하는 곳에서 발생하기 때문이고, 변경 메서드도 변경에만 집중하면 되기 때문에 유지보수가 더 좋아진다.


참고

https://jiwondev.tistory.com/225
https://walbatrossw.github.io/jpa/2019/03/14/jpa-persistence-context.html
https://velog.io/@syleemk/JPA-%EC%98%81%EC%86%8D%EC%84%B1-%EA%B4%80%EB%A6%AC
https://www.inflearn.com/questions/27795
https://www.inflearn.com/questions/152202
글에서 잘못된 점이나 궁금한 점은 댓글로 남겨주세요🧐

profile
스프린트가 아닌 사이클링

0개의 댓글