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);
}
- save()하면 영속성컨텍스트에 먼저 저장하게된다.
- 모든작업이 끝나고 flush가 호출될 때 그제서야 DB에 저장하게 된다.
- flush가 됐더라도 여전히 영속성컨텍스트에 save()한 객체가 남아있다.
- 따라서 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를 반환한다.