20190710 [jpa] JPA 알아보기 03 : TestEntityManager 살펴보기 (수정 20190817)
Spring/Spring JPA 2019. 7. 10. 22:16TestEntityManager
Alternative to EntityManager for use in JPA tests.
Provides a subset of EntityManager methods that are useful for tests
as well as helper methods for common testing tasks such as persist/flush/find.
JPA 테스트를 하기위한 대안으로써,
엔티티매니저의 기본적인 메소드를 제공함과 동시에 테스트하기 유용하다.
또한 헬퍼 메소드를 제공하는데 그에 따른 내용은 persist(), flush(), find() 등 이 존재한다.
대략적으로 나는 아래와 같이 JPA 테스트를 시작한다.
@RunWith(SpringRunner.class)
@DataJpaTest
@EnableJpaAuditing
@Slf4j
public class AlbumJpaTest {
@Autowired
private TestEntityManager testEntityManager;
@Autowired
private AlbumRepository albumRepository;
@Autowired
private AlbumPhotoRepository albumPhotoRepository;
@Autowired
private AlbumCommentRepository albumCommentRepository;
// 중략
}
TestEntityManager 에는 일반적으로 EntityManager 에 있는 메소드들을 다 제공해주고 있는 것 같다.
void clear()
- EntityManager.clear() 와 동일
- all managed entities to become detached, Clear the Persistence Context
- 관리되고 있는 모든 엔티티들을 준영속 상태(detached)로 변경시킨다. 영속성 컨텍스트를 깨끗히 비운다.
void detach(Object entity)
- EntityManager.detach(Object) 와 동일
- a managed entity to become detached, Remove the given entity from Persistence Context
- 영속성 상태에 있는 특정한 엔티티를 준영속 상태로 변경시킨다. 결과적으로 엔티티 매니저는 해당 엔티티를 관리하지 않는 상태에 두고 있다.
<E> E refresh(E Entity)
- EntityManager.refresh(Object) 와 동일
- overwriting changes made to the entity, Refresh the state of the instance from database
- 데이터베이스에서 엔티티에 대한 상태값을 가져와서 덮어씌운다.
void flush()
- EntityManager.flush() 와 동일
- Synchronize the persistence context to the underlying database
- 영속성 컨텍스트에 있는 엔티티의 변경내용을 가지고 데이터베이스와 동기화 시키는 작업이다. flush() 를 수행하면 데이터베이스에 영구적으로 반영된다.
void remove(Object entity)
- EntityManager.remove(Object) 와 동일
- Remove the entity instance
- 영속성 컨텍스트에 있는 엔티티를 삭제하며, 데이터베이스에서도 해당 엔티티를 삭제한다.
<E> E merge(E entity)
- EntityManager.merge(Object) 와 동일
- Merge the state of the given into the current persistence context
- 준영속상태에 있는 엔티티를 영속상태로 변경시킨다.
<E> E persist(E entity)
- EntityManager.persist(Object) 와 동일
- Make an instance managed and persistence, then return original source entity
- 새롭게 만들어진 엔티티에 대해서 영속성 컨텍스트에 존재하게 하며, 엔티티 매니저에 의해 관리되게 한다. 이후 기본 엔티티의 값을 반환한다. 추가적으로 파라미터로 받은 엔티티 또한 영속성 컨텍스트에 포함된다.
<E> E find(Class<E> entityClass, Object primaryKey)
- EntityManager.find(entityClass, primaryKey) 와 동일
- Find by primary key.
- 만약에 find() 메소드를 수행할 시 영속성 컨텍스트에 엔티티가 존재하면 데이터베이스에 select 쿼리를 날리지 않는다. 바로 영속성 컨텍스트 내에 존재하므로 거기서 바로 조회한다. 이를 1차 캐시 조회라고 부른다.
TestEntityManager 그리고 EntityManager 에 있는 내용들은 JPA 엔티티 상에서 연관관계 cascade = CascadeType 과 관련이 있다.
- @OneToOne
- @OneToMany
- @ManyToOne
- @ManyToMany
Cascade Type
-
cascade = CascadeType.PERSIST
만약에 엔티티가 영속상태 또는 저장상태가 되었다면, 연관된 엔티티들도 영속상태가 된다. -
cascade = CascadeType.REMOVE
만약에 엔티티가 제거 또는 삭제되면, 연관된 엔티티들도 삭제 또는 제거 된다. -
cascade = CascadeType.REFRESH
만약에 엔티티가 리프레쉬되면, 연관된 엔티티들도 리프레쉬 된다. -
cascade = CascadeType.DETACH
만약에 엔티티가 디태치되면, not associated w/ session 이면 연관된 엔티티들도 디태치된다. -
cascade = CascadeType.MERGE
만약에 엔티티가 머지되면 연관된 엔티티들도 머지된다. -
cascade = CascadeType.ALL
PERSIST, REMOVE, REFRESH, DETATCH, MERGE 를 포함한다.
1차 캐시 조회
@Test
public void persistAndFindTest(){
Album album = Album.builder()
.content("콘택트 보고 댓글좀")
.build();
testEntityManager.persist(album);
/**
* 해당 내용이 존재 또는 미존재 하냐에 따라서 select 쿼리가 결정된다.
* 왜냐하면 영속성 컨텍스트에 해당 엔티티의 내용이 존재여부가 쿼리 날리는 것이랑 연관이 있기 때문
* **/
testEntityManager.clear();
testEntityManager.find(Album.class, 1L);
}
동일성 보장
@Test
public void persistAndFindAndFindTest_동일성_보장_테스트(){
Album album = Album.builder()
.content("컨택트 보고 댓글좀")
.build();
testEntityManager.persist(album);
testEntityManager.clear();
/**
* find() 함수 두 번 호출
* 그러나, 쿼리는 한 번 날라감
* **/
Album foundAlbum1 = testEntityManager.find(Album.class, 1L);
Album foundAlbum2 = testEntityManager.find(Album.class, 1L);
assertThat(foundAlbum1, is(foundAlbum2));
}
Hibernate:
select
album0_.id as id1_0_0_,
album0_.create_date as create_d2_0_0_,
album0_.update_date as update_d3_0_0_,
album0_.content as content4_0_0_
from
album album0_
where
album0_.id=?
글을 작성하다가 알게된 사항인데, 여기 링크에 매우 자세히 설명되어 있다. 나도 내용을 보면서 보충할 내용을 보충하는 것이 좋을 것 같다.
'Spring > Spring JPA' 카테고리의 다른 글
20201001 [jpa] JPA N+1 문제를 만들어보고 해결해보기. (수정 2020-10-05) (0) | 2020.10.01 |
---|---|
20190919 [jpa] 스프링 테스트 코드 상에서 DB 에 데이터 적재. (0) | 2019.09.19 |
20190720 [문제해결] Infinite recursion (StackOverflowError) (3) | 2019.07.20 |
20190602 [jpa] JPA 알아보기 02 : JPA & Hibernate & Spring Data JPA (0) | 2019.06.02 |
20181209 [jpa] JPA 알아보기 01 (수정 20190601) (0) | 2018.12.09 |