1 분 소요

JPA Hint

JPA 쿼리 힌트 (SQL 힌트가 아니라 JPA 구현체에게 제공하는 힌트)

쿼리 힌트 사용

1
2
@QueryHints(value = @QueryHint(name="org.hibernate.readOnly", value = "true"))  
Member findReadOnlyByUsername(String username);

다음과 같이 사용하면 여기서 생성된 엔티티는 readOnly가 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
@Test  
public void queryHint() throws Exception {  
    //given  
    Member member1 = memberRepository.save(new Member("member1", 10));  
    em.flush(); // 인서트  
    em.clear(); // 영속성 컨텍스트 날림  
    //when  
    Member findMember = memberRepository.findById(member1.getId()).get();  
    findMember.setUsername("member2");  
    //then  
  
    em.flush(); // 업데이트 (변경감지)  
}

이런 테스트가 있다고 보면 쿼리가 인서트 제외하고, 2번 나가게 될 것이다. findById()에서 select

setUsername 때문에 em.flush() 에서 업데이트

만약에 가져온 엔티티를 업데이트를 막기 위해선 JPA 쿼리 힌트를 사용하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
@Test  
public void queryHint2() throws Exception {  
    //given  
    Member member1 = memberRepository.save(new Member("member1", 10));  
    em.flush(); // 인서트  
    em.clear(); // 영속성 컨텍스트 날림  
    //when  
    Member findMember = memberRepository.findReadOnlyByUsername("member1");  
    findMember.setUsername("member2");  
    //then  
  
    em.flush(); // 업데이트 (변경감지)  
}

메서드만 findReadOnlyByUsername로 바꿔서 동일하게 테스트를 진행해보면

바뀌지 않고 끝나버린 것을 볼 수 있다.

JPA Lock

1
2
@Lock(LockModeType.PESSIMISTIC_WRITE)  
List<Member> findLockByUsername(String username);

이런 식으로 스프링 데이터 JPA에서는 JPA에 Lock 기능을 다음과 같이 사용할 수 있다.

잘 사용하지 않아서, 사용하려면 제대로 찾아보고 사용하자.

아무튼

select 절에 for update 이런 식으로 나간다. 이러면 그 세션 에서 업데이트 하지 않는 이상 다른 곳에서 그 특정 데이터를 못 건드리게 된다.

태그: ,

카테고리:

업데이트:

댓글남기기