특징

  • Java identity: a==b
  • Database identity: x.getId().equals(y.getId())
  • Scope of object identity: Java Identity와 Database identity모두 보장되는 상태.

Scope of object identity 종류

  • No identity scope: 하나의 DB 레코드가 같은 자바 객체로 여러번 애플리케이션으로 반환되든지
    말든지 신경 안 쓴다. 문제가 생긴다. (만약에 두 개의 객체가 하나의 레코드를 표현하고 있는데, 그 두 개의 객체의 정보를
    수정하면, DB에는 어떤 객체의 변화를 반영해야 하는가? 어떻게 하든 둘 중 하나는 손실 되겠군.)
  • Persistence context-scoped identity: 단일 Persistence context
    내부에서는 오직 하나의 객체만이 하나의 DB 레코드를 표현할 수 있도록 보장한다. 위에서 언급했던 문제가 없어지고 context
    레벨에서의 cache를 보장할 수 있다.
  • Process-scoped identity: 한 단계 더 나가서, 전체 JVM 프로세스 내부에서 오직 하나의 객체만이 하나의 DB 레코드를 표현할 수 있다.
  • 하이버는 persistence context-scope으로 구현했다.

Persistence context-scope 예제

@Test
public void persistenceContextScope() throws Exception {
Session session = sessionFactory.openSession();
Member member = new Member();
session.save(member);
Long memberId = member.getId();

Member loadedMember1 = (Member) session.get(Member.class, memberId);
Member loadedMember2 = (Member) session.get(Member.class, memberId);

// Java Identity In Persistence Context
assertTrue(loadedMember1 == loadedMember2);
// DB Identity In Persistence Context
assertTrue(loadedMember1.getId().equals(loadedMember2.getId()));
session.flush();
session.close();

Session session2 = sessionFactory.openSession();
Member loadedMember3 = (Member) session2.get(Member.class, memberId);

// Java Identity Out Persistence Context
assertFalse(loadedMember1 == loadedMember3);

// DB Identity Out Persistence Context
assertTrue(loadedMember1.getId().equals(loadedMember3.getId()));

session2.flush();
session2.close();
}
  • Persistent Context 내에서는(Persistent 상태) 같은 주키로 가져온 객체는 Java identity와 DB identity 모두 동일하다.
  • 하지만 Detached 상태의 객체와 Persistence 상태의 객체의 Java Identity는 보장되지 않는다. 물론 이 때도 주키 속성은 가지고 있으니까 DB Identity는 보장된다.
  • Detached 상태의 객체를 가지고 작업하는 것는 위와 같이 Scope of Object identity가 보장되지 않는 상태에서 작업하는 것이다.