엔티티생명주기
JPA 엔티티의 생명주기에 대해 알아보자.
엔티티 생명주기에는 영속, 비영속, 준영속, 삭제 총 4가지 상태가 있다.
비영속 (new/transient)
영속성 컨텍스트와 관계 없는 새로운 상태를 말한다. 즉, 영속성 컨텍스트 관리되기 이전의 상태.
영문 표기는 transient 인데 '일시적인' 이라는 뜻이 있다.
데이터베이스 영속성이 부여되기 전인 일시적인 상태를 의미한다.
======================
member.getId() = 1
======================
Hibernate:
/* insert jpashop.jpashop.domain.Member
*/ insert
into
Member
(city, USERNAME, street, TEAM_ID, zipcode, MEMBER_ID)
values
(?, ?, ?, ?, ?, ?)
1월 10, 2024 9:48:31 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PoolState stop
INFO: HHH10001008: Cleaning up connection pool [jdbc:h2:tcp://localhost/~/test]
Process finished with exit code 0
영속 (Managed)
엔티티가 영속성 컨텍스의 관리 대상이 된 상태.
EntityManager의 persist() 메서드의 파라미터로 넘겨지는 객체는 JPA(영속성 컨텍스트)가 관리하게 되며, 영속 상태에 들어간다.
/*생략*/
Member member = new Member();
member.setId(1L);
member.setName("chan");
System.out.println("======================");
//영속
em.persist(member);
System.out.println("member.getId() = " + member.getId());
System.out.println("======================");
tx.commit();
/*생략*/
아래 실행결과에서 주석이 먼저 출력된 후에 insert문이 실행 되는 것을 볼 수 있다.
영속성 컨텍스트의 관리를 받게되는 동시에 INSERT 쿼리를 생성해 쓰기 지연 SQL 저장소라는 공간에 넣고, 이렇게 생성된 SQL은 commit 시점에 일괄 실행된다.
======================
member.getId() = 1
======================
Hibernate:
/* insert jpashop.jpashop.domain.Member
*/ insert
into
Member
(city, USERNAME, street, TEAM_ID, zipcode, MEMBER_ID)
values
(?, ?, ?, ?, ?, ?)
1월 10, 2024 9:48:31 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PoolState stop
INFO: HHH10001008: Cleaning up connection pool [jdbc:h2:tcp://localhost/~/test]
Process finished with exit code 0
준영속(Detached)
영속성 컨텍스트로부터 분리된 상태.
영속성 컨텍스트가 제공하는 모든 기능을 이용할 수 없는 상태가 된다.
Member member = new Member();
member.setId(1L);
member.setName("chan");
System.out.println("======================");
//영속
em.persist(member);
System.out.println("member.getId() = " + member.getId());
System.out.println("======================");
em.detach(member);
Member findMember = em.find(Member.class, 1L);
System.out.println("findMember = " + findMember.getId());
select문은 나가지만
아래 결과에서 find()를 통해 select쿼리는 만들어 지지만 객체를 조회해오지 못해 NullPointerException이 발생한다.
======================
member.getId() = 1
======================
Hibernate:
select
member0_.MEMBER_ID as member_i1_0_0_,
member0_.city as city2_0_0_,
member0_.USERNAME as username3_0_0_,
member0_.street as street4_0_0_,
member0_.TEAM_ID as team_id5_0_0_,
member0_.zipcode as zipcode6_0_0_
from
Member member0_
where
member0_.MEMBER_ID=?
java.lang.NullPointerException: Cannot invoke "jpashop.jpashop.domain.Member.getId()" because "findMember" is null
at jpashop.jpashop.JpaMain.main(JpaMain.java:40)
삭제(removed)
영속성 컨텍스트에서 객체가 완전히 삭제된 상태이다.
Member member = new Member();
member.setId(1L);
member.setName("chan");
System.out.println("======================");
//영속
em.persist(member);
System.out.println("member.getId() = " + member.getId());
System.out.println("======================");
// 삭제
em.remove(member);
Member findMember = em.find(Member.class, 1L);
System.out.println("findMember = " + findMember.getId
tx.commit();
detach와 달리 find쿼리 자체가 실행되지 않고, nullponterException이 발생한다.
======================
member.getId() = 1
======================
java.lang.NullPointerException: Cannot invoke "jpashop.jpashop.domain.Member.getId()" because "findMember" is null
at jpashop.jpashop.JpaMain.main(JpaMain.java:41)
reference
자바 ORM 표준 JPA 프로그래밍
https://www.inflearn.com/course/lecture?courseSlug=ORM-JPA-Basic&unitId=21687
'JAVA' 카테고리의 다른 글
[JPA] 영속성 컨텍스트의 이점 - 동일성 보장 (0) | 2024.01.10 |
---|---|
[JPA] 영속성 컨텍스트의 이점 - 1차 캐시 (1) | 2024.01.10 |
[JPA] 엔티티 매핑 - 기본 키 매핑 (0) | 2024.01.06 |
[JPA] JPA 필드와 컬럼 매핑 (0) | 2024.01.05 |
[JPA] JPA와 영속성 컨텍스트(Persistent Context) (0) | 2023.12.29 |