JAVA/JPA

모든 JPA작업은 트랜잭션 단위 안에서 일어나야한다.

gracelove91 2019. 12. 8. 22:55

JPA와 DB설정 동작확인.

public Long save(Member member) {
    em.persist(member);
    return member.getId();
}
  • 바로 member객체를 반환안하고 id를 반환하는 이유? 커맨드를 반환하면 어떤 사이드이펙트가 일어날 지 모르기때문. 커맨드와 쿼리를 분리하자!

 

모든 jpa작업단위는 트랜잭션 단위 안에서 일어나야한다.

  • @Transactional 쓸것.
    @Test
    @Transactional
    public void testMember() throws Exception {
        //given
        Member member = new Member();
        member.setUsername("memberA");

        //when
        Long savedId = memberRepository.save(member);
//        em.flush();
//        em.clear();

        Member findMember = memberRepository.find(savedId);

        //then
        Assertions.assertThat(findMember.getId()).isEqualTo(savedId);
        Assertions.assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
        Assertions.assertThat(findMember).isEqualTo(member);
    }
  1. save()하면 영속성컨텍스트에 먼저 저장하게된다.
  2. 모든작업이 끝나고 flush가 호출될 때 그제서야 DB에 저장하게 된다.
  3. flush가 됐더라도 여전히 영속성컨텍스트에 save()한 객체가 남아있다.
  4. 따라서 save()한 member객체와 find()로 찾아온 member객체는 영속성컨텍스트 안에 있던 객체기 때문에 동일 객체다. Assertions.assertThat(findMember).isEqualTo(member);true를 반환한다.

 

하지만!

 

영속성컨텍스트를 flush와 clear메소드로 지우고 find를 한다면?
member객체를 새롭게 db에서 가져오기 때문에 save했을 때의 member객체와 find로 찾아온 member객체는 물리적동치가 아니다. 따라서 Assertions.assertThat(findMember).isEqualTo(member);false를 반환한다.