1️⃣ @DynamicInsert와 @DynamicUpdate가 무엇인지 ?
JPA의 구현체인 하이버네이트(Hibernate)에서 제공하는 어노테이션이다.
엔티티의 INSERT 및 UPDATE 쿼리를 생성하는 방식을 최적화하기 위해 사용된다.
하이버네이트가 INSERT 또는 UPDATE 쿼리를 고정된 형태가 아닌,
실제 엔티티의 상태에 따라 동적으로 생성하도록 하여 성능상 이점을 얻기 위해 사용하는 어노테이션 !
2️⃣ @DynamicInsert와 @DynamicUpdate가 어떻게 작동되는 지 ?
기존 방식
- JPA (정확히는 하이버네이트와 같은 JPA 구현체)는 기본적으로 엔티티의 영속성 상태 변화를 감지하여 자동으로 SQL 쿼리를 생성하고 실행한다.이 방식은 쿼리 생성 로직이 단순하다는 장점이 있지만, 불필요하게 많은 컬럼을 포함시키는 단점이 있다.
- 예시
- INSERT: 기본적으로 모든 컬럼을 INSERT 문에 포함시킴
- UPDATE: 업데이트 가능한 모든 컬럼을 UPDATE 문의 SET 절에 포함시킴.
@DynamicInsert, @DynamicUpdate 적용
- 1. 엔티티 클래스 레벨에 @DynamicInsert 를 붙이면 적용된다.
- 예시
- INSERT: null이 아닌 필드들만 INSERT 문에 포함시킴
- UPDATE: 엔티티가 컨텍스트에 로딩된 후 실제로 값이 변경된 필드들만 SET절에 포함시킴
3️⃣ 적용 시 장단점
| 구분 | 기존 | @DynamicInsert/Update |
| 장점 | 쿼리 생성 로직이 단순하여 하이버네이트 내부 처리 부하가 적음 | - 쿼리 문자열이 짧아지기 때문에 네트워크 부하가 줄어듦 - 불필요한 컬럼의 삽입/갱신을 막아 데이터베이스 부하를 줄일 수 있음 - null 값 삽입시 DB의 DEFAULT값이 적용되도록 유도할 수 있음. - 실제 변경된 컬럼만 갱신하여 동시성 충돌 가능성을 줄일 수 있음 |
| 단점 | - 불필요하게 많은 컬럼을 쿼리에 포함시켜 쿼리 문자열이 길어지고 네트워크 부하가 증가할 수 있음 - 데이터베이스의 DEFAULT 값이 아닌 명시적인 NULL이 삽입될 수 있음 (@DynamicInsert 시 기대하는 동작과 다를 수 있음) - 값이 변경되지 않은 컬럼도 다시 갱신하여 불필요한 쓰기 작업이 발생할 수 있음. |
어떤 컬럼을 쿼리에 포함시킬지 결정하는 추가적인 내부처리가 필요하여 하이버네이트 내부 처리 부하가 소폭 증가할 수 있음 |
4️⃣ 언제 적용하면 좋을까 ?
- 엔티티의 컬럼 수가 매우 많은 경우
- 컬럼 수가 많을 수록 불필요하게 포함되는 컬럼이 많아져 쿼리 문자열이 길어지고 네트워크 및 데이터베이스 부하가 커진다.
- INSERT 시 대부분의 컬럼이 null이거나 DB의 DEFAULT 값을 사용하고 싶은 경우
- @DynamicInsert → 명시적으로 null을 삽입하는 대신 DB의 기본값을 사용하도록 유도
- UPDATE 시 변경되는 컬럼의 수가 적은 경우
- 전체 컬럼 중 실제로 몇 개만 변경되는 경우가 빈번하다면, 변경된 컬럼만 갱신함으로써 데이터베이스 쓰기 부하를 줄이고 쿼리 크기를 최적화할 수 있음.
- 성능 최적화가 필요한 와이드(Wide) 테이블 (컬럼이 많은 테이블): 대규모 데이터 처리에서 쿼리 크기나 불필요한 쓰기 작업이 병목이 될 수 있다면 고려해볼 수 있음.
🚨 주의사항
- @DynamicInsert와 @DynamicUpdate는 하이버네이트의 확장 기능이며 표준 JPA 기능은 아니다.
- 성능 측정 없이는 명확한 효과를 단정하기 어려움. 때로는 기본 동작이 더 나은 성능을 보이기도 함.
- 단순히 컬럼 수가 적고 변경이 잦은 테이블에는 큰 이점이 없을 수 있으며, 오히려 내부 처리 부하 때문에 미미하게나마 성능 저하가 있을 수 있음.
'SpringBoot' 카테고리의 다른 글
| [SpringBoot][GPT] SpringBoot와 OpenAI API 연결하기 (0) | 2025.04.29 |
|---|---|
| 서블릿 vs. Spring MVC 비교 (0) | 2025.04.07 |
| AOP(Aspect-Oriented Programming) (0) | 2025.04.07 |
| [SpringBoot] 자동 삭제 기능 구현 Scheduled Job (0) | 2025.01.21 |
| [SpringBoot] API & Paging (0) | 2024.11.22 |