find() 메소드를 사용한다.
find(), JPQL을 사용한 조회도 영속 상태가된다.
Menu foundMenu = entityManager.find(Menu.class, menuCode); 력하
영속성 컨텍스트 내부에 캐시를 가지고 있는데 이를 1차 캐시라한다.
영속성 컨텍스트 내부에 Map이 하나 있는데 키는 @Id로 매핑한 식별자고, 값은 엔터티 인스턴스이다.
식별자 값은 데이터베이스 기본 키와 매핑되어있다.
따라서 영속성컨텍스트에 데이터를 저장하고 조회하는 모든 기준은 데이터베이스 기본 키 값이다.
persist(); 메소드를 통해 엔터티를 영속시키면
1차 캐시에 저장된다.
트랜젝션 관리가 필요하다.
//given
Menu menu = new Menu();
menu.setMenuName("JPA 테스트용 신규 메뉴");
menu.setMenuPrice(5000);
menu.setCategoryCode(4);
menu.setOrderableStatus("Y");
//when
EntityTransaction entityTransaction = entityManager.getTransaction();
entityTransaction.begin();
try {
entityManager.persist(menu);
entityTransaction.commit();
} catch (Exception e){
entityTransaction.rollback();
e.printStackTrace();
}
//then
assertTrue(entityManager.contains(menu));
JPA가 엔터티를 수정하는 방법
엔터티의 변경사항을 데이터 베이스에 자동으로 반영하는 변경감지(dirty checking)
기능을 사용한다.
변경감지(dirty checking)
란?
JPA는 최초 상태를 복사해서 저장해두는데 이것을 스냅샷이라한다. 플러시 시점에 스냅샷과 엔터티를 비교해서 변경된 엔터티를 찾아 변경한다.
자바ORM표준 JPA프로그래밍 저자 김영한 참고 자료
변경감지는 영속성 컨텍스트가 관리하는 영속 상태의 엔터티에만 적용된다.
@Test
public void 메뉴_이름_수정_테스트() {
//given
Menu menu = entityManager.find(Menu.class, 2); //2번 메뉴코드를 가진 entity를 찾는 코드
System.out.println("menu = " + menu);
String menuNameToChange = "우럭뽈살젤리"; // 바꾸고 싶은 이름
//when
EntityTransaction entityTransaction = entityManager.getTransaction();
entityTransaction.begin();
try {
menu.setMenuName(menuNameToChange);
entityTransaction.commit();
} catch (Exception e) {
entityTransaction.rollback();
e.printStackTrace();
}
//then
assertEquals(menuNameToChange, entityManager.find(Menu.class, 2).getMenuName());
}
@Test
public void 메뉴_삭제하기_테스트() {
//given
Menu menuToRemove = entityManager.find(Menu.class, 1);
//when
EntityTransaction entityTransaction = entityManager.getTransaction();
entityTransaction.begin();
try {
entityManager.remove(menuToRemove);
entityTransaction.commit();
} catch (Exception e) {
entityTransaction.rollback();
e.printStackTrace();
}
//then
Menu removeMenu = entityManager.find(Menu.class, 1);
assertEquals(null, removeMenu);
}