* 동일한 트랜잭션 내에서 같은 엔티티를 조회할 때 JPA가 제공하는 1차 캐시(엔티티 매니저 컨텍스트)로 인해 동일한 객체 인스턴스를 반환하는지 확인하는 방법
Member m1 = repo.findById(dto.getNum()).get();
Member m2 = repo.findById(dto.getNum()).get();
boolean isEqual = m1 == m2;
System.out.println("m1과 m2가 같냐?" + isEqual);
이 코드의 목적은 동일한 트랜잭션 내에서 같은 엔티티를 조회할 때 JPA가 제공하는 1차 캐시(엔티티 매니저 컨텍스트)로 인해 동일한 객체 인스턴스를 반환하는지를 확인하기 위함입니다.
JPA의 1차 캐시
1) 1차 캐시:
- JPA 엔티티 매니저는 1차 캐시(엔티티 매니저 컨텍스트)를 사용하여 동일한 트랜잭션 내에서 동일한 엔티티를 조회할 때 동일한 객체 인스턴스를 반환합니다.
- 즉, 같은 엔티티를 여러 번 조회하더라도, 처음 조회된 엔티티 객체를 1차 캐시에 저장하고, 이후 동일한 엔티티를 다시 조회할 때 1차 캐시에서 반환합니다. 이를 통해 데이터베이스 접근을 최소화하고 성능을 최적화할 수 있습니다.
2) 트랜잭션 내에서의 동작:
- 트랜잭션 내에서 repo.findById(dto.getNum()).get()을 호출하면, JPA는 먼저 1차 캐시에서 해당 엔티티를 찾습니다.
- 1차 캐시에 엔티티가 존재하면, 데이터베이스를 다시 조회하지 않고 캐시에 저장된 객체를 반환합니다.
- 이로 인해 m1과 m2는 동일한 인스턴스를 가리키게 됩니다.
동일성 확인:
- m1 == m2는 두 객체가 동일한 인스턴스인지를 확인합니다.
- 동일한 트랜잭션 내에서 같은 엔티티를 두 번 조회하면 동일한 객체 인스턴스를 반환하는지 확인할 수 있습니다.
- System.out.println("m1과 m2가 같냐?" + isEqual);는 이를 출력하여 실제로 동일한 객체인지를 확인합니다.
예제 설명
@Transactional
@Override
public void update2(MemberDto dto) {
// 수정할 회원의 번호를 이용해서 회원 정보 entity 객체 얻어내기
Member m1 = repo.findById(dto.getNum()).get();
Member m2 = repo.findById(dto.getNum()).get();
// 동일성 검사
boolean isEqual = m1 == m2;
System.out.println("m1과 m2가 같냐?" + isEqual);
// setter 메소드를 이용해서 이름과 주소 수정하기
m1.setName(dto.getName());
m1.setAddr(dto.getAddr());
}
- @Transactional 어노테이션
: 이 메서드가 트랜잭션 내에서 실행됨을 보장합니다. 트랜잭션이 시작되고 메서드 실행이 완료되면 트랜잭션이 커밋되거나 롤백됩니다.
: 동일한 트랜잭션 내에서 동일한 엔티티를 여러 번 조회해도 1차 캐시로 인해 같은 객체 인스턴스를 반환하게 됩니다.
- 동일한 엔티티 두 번 조회
: Member m1 = repo.findById(dto.getNum()).get();
: Member m2 = repo.findById(dto.getNum()).get();
: 두 번 조회하지만, 동일한 트랜잭션 내에서 JPA 1차 캐시 덕분에 동일한 객체를 가리키게 됩니다.
- 동일성 검사 및 출력
: boolean isEqual = m1 == m2;
: System.out.println("m1과 m2가 같냐?" + isEqual);
: 두 객체가 동일한 인스턴스인지 확인하고 이를 출력합니다. 동일한 트랜잭션 내에서는 true가 출력됩니다.
- 엔티티 수정
: m1.setName(dto.getName());
: m1.setAddr(dto.getAddr());
: 동일한 객체의 필드를 수정하면 JPA가 트랜잭션 종료 시점에 변경 사항을 감지하고 데이터베이스에 자동으로 반영합니다.
그래서 위 코드는 동일한 트랜잭션 내에서 동일한 엔티티를 조회할 때 JPA가 동일한 객체 인스턴스를 반환하는지를 확인하기 위한 것입니다. JPA의 1차 캐시 덕분에 동일한 트랜잭션 내에서는 동일한 엔티티를 여러 번 조회하더라도 동일한 객체를 반환합니다. 이를 통해 데이터베이스 접근을 최소화하고 성능을 최적화할 수 있습니다.