2019. 6. 17. 14:45ㆍ[정리] 기능별 개념 정리/JPA
@Data
@Entity("member")
public class MemberEntity{
@Id
@GeneratedValue
private long id;
private String name;
private int age;
}
public interface MemberRepository extends JpaRepository<MemberEntity, Long> {
}
@RunWith(SpringRunner.class)
@DataJpaTest
@EnableAutoConfiguration
@ContextConfiguration(classes = {MemberRepository.class})
public class MemberRepositoryTest {
@Autowired
private MemberRepository = memberRepository;
@Test
public void test() {
MemberEntity memberEntity = new MemberEntity();
memberEntity.setName("kok202");
memberEntity.setAge(99);
// 1번 : Insert
memberRepository.save(memberEntity);
// 2번 : Select
memberEntity = memberRepository.findById(memberEntity.getId()).get();
// 3번 : Update
memberEntity.setAge(100);
// 4번 : Delete
memberRepository.delete(memberEntity);
}
}
@DataJpaTest 안에 @Transactional 이 있다.
코드 자체는 문제없는 코드다.
1번 : Insert 쿼리가 날라가지 않는다. memberEntity 는 영속성 컨텍스트 안에 들어가있을 뿐이다. Session 이 commit 될 때 영속성 컨텍스트안의 데이터가 전송된다. 단 이 때 오히려 memberEntity 에 들어가야하는 Id 값이 몇인지 알기 위해 Senquence 를 select 해오는 쿼리가 발생한다. 그리고 1번 save 의 결과로 memberEntity 안의 Id 에는 Sequnce 에서 읽어온 값이 들어가게 된다.
2번 : Select 쿼리가 날라가지 않는다. 영속성 컨텍스트 안에 이미 데이터가 있기 때문이다. 그냥 이를 읽어온다.
3번 : Update 쿼리가 날라가지 않는다. 마찬가지로 Session 이 commit 될 때 영속성 컨텍스트안의 데이터를 DB로 전송하려 시도한다.
4번 : Delete 쿼리가 날라가지 않는다. Session 은 종료됬고 commit 을 시도한다. 하지만 영속성 컨텍스트 안에서 해당 엔티티가 삭제가 되어야 한다는 마킹이 되어있다. 어차피 이제껏 DB 에 데이터를 저장한 적이 없으므로 delete 도 발생시키지 않는다.
결과론적으로 insert, select, update, delete 쿼리가 발생하지 않는다.
@RunWith(SpringRunner.class)
@DataJpaTest
@EnableAutoConfiguration
@ContextConfiguration(classes = {MemberRepository.class})
public class MemberRepositoryTest {
@Autowired
private MemberRepository = memberRepository;
@Test
public void test() {
MemberEntity memberEntity = new MemberEntity();
memberEntity.setName("kok202");
memberEntity.setAge(99);
// 1번 : Insert
memberRepository.save(memberEntity);
memberRepository.flush();
// 2번 : Select
memberRepository.clear();
memberEntity = memberRepository.findById(memberEntity.getId()).get();
// 3번 : Update
memberEntity.setAge(100);
memberRepository.flush();
// 4번 : Delete
memberRepository.delete(memberEntity);
}
}
1번 : Insert 쿼리가 발생한다. save 이후 flush 를 해줘서 영속성 컨텍스트의 데이터를 DB 에 반영시켰다.
2번 : Select 쿼리가 발생한다. find 이전에 clear 를 해줘서 영속성 컨텍스트의 초기화 시켰다.
3번 : Update 쿼리가 발생한다. 영속성 컨텍스트 안의 데이터가 변경되었고 엔티티 매니저가 이를 감시해서 알고 있다. flush 를 해줘서 영속성 컨텍스트의 데이터를 DB 에 반영시켰다.
4번 : Delete 쿼리가 발생하지 않는다. 메소드의 종료와 함께 Session 이 종료되었으므로 굳이 commit 이나 flush 하지 않아도 commit이 되서 delete 쿼리도 발생해야할 것 같다. 하지만 테스트 케이스의 트랜잭션은 Default 가 Rollback 이다. 이를 JPA 는 알고 있다. 어차피 Rollback 될 것이므로 굳이 Delete 쿼리를 발생시키지 않는다.
@RunWith(SpringRunner.class)
@DataJpaTest
@EnableAutoConfiguration
@ContextConfiguration(classes = {MemberRepository.class})
public class MemberRepositoryTest {
@Autowired
private MemberRepository = memberRepository;
@Test
public void test() {
MemberEntity memberEntity = new MemberEntity();
memberEntity.setName("kok202");
memberEntity.setAge(99);
// 1번 : Insert
memberRepository.save(memberEntity);
memberRepository.flush();
// 2번 : Select
memberRepository.clear();
memberEntity = memberRepository.findById(memberEntity.getId()).get();
// 3번 : Update
memberEntity.setAge(100);
memberRepository.flush();
// 4번 : Delete
memberRepository.delete(memberEntity);
memberRepository.flush();
}
}
1번 : Insert 쿼리가 발생한다. save 이후 flush 를 해줘서 영속성 컨텍스트의 데이터를 DB 에 반영시켰다.
2번 : Select 쿼리가 발생한다. find 이전에 clear 를 해줘서 영속성 컨텍스트의 초기화 시켰다.
3번 : Update 쿼리가 발생한다. 영속성 컨텍스트 안의 데이터가 변경되었고 엔티티 매니저가 이를 감시해서 알고 있다. flush 를 해줘서 영속성 컨텍스트의 데이터를 DB 에 반영시켰다.
4번 : Delete 쿼리가 발생한다. delete 이후 flush 를 해줘서 영속성 컨텍스트의 데이터를 DB 에 반영시켰다.
'[정리] 기능별 개념 정리 > JPA' 카테고리의 다른 글
Persist vs Merge (0) | 2020.02.04 |
---|---|
영속성 컨텍스트 정리 (2) (1) | 2019.11.14 |
JPA : Embeddable (0) | 2019.06.17 |
@EntityGraph : FetchType.EAGER 일 경우 Select 쿼리 줄이기 (1) | 2019.06.15 |
JPA fetch 맵핑별 기본값 (0) | 2019.06.14 |