JPA-04 EntityLifeCycle

yj k·2023년 4월 9일
0

jpa

목록 보기
4/14

엔터티의 생명주기

  1. 비영속 : 영속성 컨텍스트와 전혀 관계가 없는 상태
  2. 영속 : 영속성 컨텍스트에 저장된 상태
  3. 준영속 : 영속성 컨텍스트에 저장되었다가 분리된 상태
  4. 삭제 : 삭제된 상태


1. 비영속

객체만 생성하면 영속성 컨텍스트나 데이터베이스와 관련없는 비영속 상태이다.


2. 영속

엔티티 매너지가 영속성 컨텍스트에 엔티티 객체를 저장하면 영속성 컨텍스트가 엔티티 객체를 관리하게되고 이를 영속 상태라고 한다.
find(), JPQL을 사용한 조회도 영속 상태가된다.

persist(menu) 메소드를 통해 엔터티를 영속

3. 준영속

영속성 컨텍스트가 관리하던 엔티티 객체를 관리하지 않는 상태가 된다면 준영속 상태라고 한다.
detach() : 특정 엔티티만 준영속 상태로 만든다.
clear() : 영속성 컨텍스트를 초기화. 해당 영속성 컨텍스트의 모든 엔터티를 준영속상태로 만든다. 1차 캐시의 내용이 삭제된다.
close() :해당 영속성 컨텍스트가 관리하던 영속 상태의 엔터티가 모두 준영속 상태가된다. 1차 캐시 공간 자체가 사라진다.

준영속 상태의 엔터티를 다시 영속 상태로 변경하려면 merge(병합)를 사용한다.

merge()메소드 : 준영속 상태의 엔티티를 받아서 그 정보로 새로운 영속상태의 엔터티를 반환한다.
준영속 상태의 엔티티가 영속상태로 바뀌는 것은 아니고, 그 값을 받은 새로운 영속 상태의 엔터티가 반환되는 것.
조회할 수 없는 데이터(ex. 비영속 컨텍스트)의 경우 새로 생성해서 병합한다.
병합은 준영속, 비영속 상관없이 식별자값으로 엔터티를 조회할 수 있다면 병합이 가능하다.
조회할수 없다면 새로 생성하는 것.

@Test
	public void 병합_merge_수정_테스트() {
		
		//given
		Menu menuToDetach = entityManager.find(Menu.class, 2);
		entityManager.detach(menuToDetach); 					//준영속상태로 만듦
		System.out.println("menuToDetach1 : " + menuToDetach);	//우럭뽈살
		
		
		//when
		menuToDetach.setMenuName("수박죽");						//수박죽 값 넣음
		System.out.println("menuToDetach2 : " + menuToDetach);	//수박죽
		
		Menu refoundMenu = entityManager.find(Menu.class, 2);	//영속상태 우럭뽈살 조회됨
		System.out.println("refoundMenu : " + refoundMenu);		//우럭뽈살
		
		/* 준영속 엔티티와 영속 엔티티의 해쉬코드는 다른 상태이다. */
		System.out.println(menuToDetach.hashCode());
		System.out.println(refoundMenu.hashCode());
		
		entityManager.merge(menuToDetach);						// 준영속 상태로 만든 것을 다시 병합

		//then
		Menu mergeMenu = entityManager.find(Menu.class, 2);		// menuToDetach가 가진 값만 병합, hash값은 refoundMenu 그대로
		assertEquals("수박죽", mergeMenu.getMenuName());
		System.out.println("mergeMenu : " + mergeMenu);
		System.out.println("menuToDetach Hash : " + menuToDetach.hashCode());
		System.out.println("refoundMenu Hash : " + refoundMenu.hashCode());
		System.out.println("mergeMenu Hash : " + mergeMenu.hashCode());				
		
		
	}

	@Test
	public void 병합_merge_삽입_테스트() {
		
		//given
		Menu menuToDetach = entityManager.find(Menu.class, 2);
		entityManager.detach(menuToDetach);
		
		//when
		menuToDetach.setMenuCode(999);			//DB에서 조회할 수 없는 키 값으로 변경
		menuToDetach.setMenuName("수박죽");
		
		entityManager.merge(menuToDetach);		// 영속 상태의 엔티티와 병합(현재는 없기때문에 삽입된다.)
		
		//then
		Menu mergeMenu = entityManager.find(Menu.class, 999);
		assertEquals("수박죽", mergeMenu.getMenuName());
		
		
	}

  • 준영속 상태의 특징
  1. 거의 비영속 상태에 가깝다.
  2. 식별자 값을 가지고 있다.
  3. 지연 로딩을 할 수 없다.

4. 삭제

엔티티를 영속성 컨텍스트 및 데이터베이스에서 삭제한다.
단, 트랜젝션을 제어(commit)하지 않으면 영구 반영되지는 않는다.
트랜젝션을 커밋하는 순간 영속성 컨텍스트에서 관리하는 엔티티 객체가 데이터 베이스에 반영되게된다. (이를 flush라한다.)
flush : 영속성 컨텍스트의 변경 내용을 데이터 베이스에 동기화하는 작업(등록, 수정, 삭제한 엔티티를 데이터베이스에 반영)

0개의 댓글