YoungSoo

[Spring JPA] Merge와 Save의 차이 본문

BE/Spring

[Spring JPA] Merge와 Save의 차이

YoungSooSoo 2023. 5. 11. 01:36

Furry_Friend_v1과 v2의 차이

많은 코드를 변경하고 있습니다. 그중에서 v1에서는 EntityManager을 사용해 데이터 베이스에 CRUD 작업을 수행해 주었는데 v2에서는 Spring Data JPA를 통해 CRUD를 작성해 주었습니다.

 

왜 EntityManager를 사용했었는데?

JPA의 EntityManager를 통해 작성한 이유는 처음 JPQL과 EntityManager를 사용해 JPA의 핵심 개념과 동작 방식을 직접  이해하기 위해서 사용했습니다. 이후에 Data JPA의 기본 CRUD 메서드를 학습했고, v2에서는 Data JPA를 통해 Repository를 구현해 주었습니다.

 

영속성 컨텍스트

먼저 이 둘의 차이를 이해하려면 영속성 컨텍스트에 대해 이해해야 했습니다.

영속성 컨텍스트는 JPA에서 엔티티를 관리하는 논리적인 영역입니다. 쉽게 말해 애플리케이션과 데이터베이스의 중간 계층이라고 생각하면 쉽습니다.

 

주요한 역할 및 특징이 5가지가 있습니다.
1. 엔티티의 관리 : 엔티티의 상태를 추적해 엔티티 객체가 영속성 컨텍스트에 등록되면 엔티티의 변경사항을 추적하고 데이터베이스와의 동기화를 담당해 줍니다.

2. 1차 캐시 : 영속성 컨텍스트 내부에 존재하는 캐시를 말합니다.

3. 트랜잭션을 지원하는 쓰기 지연 : 바로 데이터베이스에 저장을 하는 것이 아닌 내부 쿼리 저장소에 SQL을 모아뒀다가 트랜잭션을 커밋할 때 한 번에 보냅니다.

4. 트랜잭션 범위 : 영속성 컨텍스트는 트랜잭션 범위 내에서 동작하는데 트랜잭션을 시작하고 커밋할 때, 엔티티의 변경사항을 데이터베이스에 동기화합니다. 이를 통해 데이터베이스와의 일관성을 유지합니다.

5. 더티 체킹 : 영속성 컨텍스트는 엔티티의 변경사항을 추적하여 자동으로 업데이트 쿼리를 생성합니다.

 

어떤 차이점이 있었지?

장바구니 담기 기능을 구현할 때 v1에서는 왼쪽 사진을 v2에서는 단순히 save를 통해 구현했습니다.

먼저 바뀐 점은 이전에는 Service와 Controller를 아무렇게나 사용했었는데 비즈니스 로직을 Service에서 작성해 주었다는 점도 바뀌었습니다. Service와 Controller를 나누면 관심사의 분리와 캡슐화를 도모하는데 도움 등을 고려했을 때 이점이 있어서 분리하여 개발하였습니다.

왼쪽은 merge를 통해 구현한 것이고 오른쪽은 save를 통해 구현했습니다.

Furry_Friend_v1                                                                                               Furry_Friend_v2                                

merge를 사용한 이유는 유연한 업데이트와 저장을 위해 사용했습니다. merge를 사용하면 먼저 엔티티의 상태를 확인하고 PK를 기준으로 영속성 컨텍스트에서 관리되는지 여부를 판단합니다. 엔티티가 준영속 상태라면 새로운 영속 엔티티를 생성합니다. 하지만 영속 상태라면 변경사항을 업데이트합니다.

save의 대한 설명은 아래 링크를 참고해 주시면 감사하겠습니다.

https://youngsoosoo.tistory.com/213

 

결과적으로 변경하고 나서,,,

두 개를 변경했을 때 성능적인 면에서 큰 차이는 없습니다. 하지만 자동으로 식별자를 관리해 주고, save를 사용한다면 더티 체킹을 통해 변경사항을 자동으로 감지하여 적절한 업데이트 쿼리를 수행해 줍니다. 또한 특정 상황에서는 merge를 사용해도 되지만 지금 저와 같은 상황은 save를 사용하는 것이 좋을 거 같습니다.

물론 사용하기 전에 Data JPA에서 제공해 주는 기본 CRUD에 대한 동작방식을 알고 사용하는 것이 정말 중요한 거 같습니다.