kok202
JPA : Query 발생 시점

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 에 반영시켰다.