정구리의 우주정복

[Kotlin] Dirty Checking (더티 체킹) 본문

JAVA/STUDY

[Kotlin] Dirty Checking (더티 체킹)

Jungry_ 2025. 2. 2. 22:22
반응형

 

    @Transactional
    override fun deleteRoutine(userId:Long, routineId: Long): Long {
        // routine entity 가져와서
        val deleteRoutine = routineRepository.findById(routineId).orElseThrow {IllegalArgumentException("routine not found")}
        // 유저 유효한지 확인하고
        val loginUser = userRepository.findById(userId).orElseThrow {IllegalArgumentException("user not found")}

        if (deleteRoutine.user.id != loginUser.id) {
            throw IllegalArgumentException("작성한 사용자만 삭제할 수 있습니다")
        }
        // is deleted true 로 변경 후 save dirty check 로 인해서 알아서 업데이트 됨
        deleteRoutine.delete()

        // 그럼 이거 save 쓰면 쿼리 두번 도나 ?
//        routineRepository.save(deleteRoutine)

        return deleteRoutine.id
    }

 

JPA의 영속성 컨텍스트(Persistence Context)는 엔티티가 변경되면 자동으로 감지하여 UPDATE를 수행하는 기능

 

한마디로 뭔가 바뀌면 알아서 감지해서 update 를 해주는 아주 멋진 기능

 

JPA 엔티티는 기본적으로 Dirty Checking을 지원하므로 save() 없이도 변경이 반영된다

 

그럼 만약에 Dirty Checking 하고나서 save 를 한번 더 하면 쿼리가 두번 실행될까 ?

 

궁금하다 궁금해

 

spring:
  jpa:
    show-sql: true 
    properties:
      hibernate:
        format_sql: true
        use_sql_comments: true 
        highlight_sql: true

 

설정을 켜주고 동작시켜보자

 

(1) save 켠 경우

[Hibernate] 
    select
        re1_0.id,
        re1_0.completed_count,
        re1_0.created_at,
        re1_0.end_date,
        re1_0.goal_count,
        re1_0.is_deleted,
        re1_0.is_success,
        re1_0.name,
        re1_0.start_date,
        re1_0.updated_at,
        re1_0.user_id 
    from
        routines re1_0 
    where
        re1_0.id=?
[Hibernate] 
    select
        ue1_0.id,
        ue1_0.created_at,
        ue1_0.email,
        ue1_0.level,
        ue1_0.name,
        ue1_0.points 
    from
        users ue1_0 
    where
        ue1_0.id=?
[Hibernate] 
    /* update
        for com.example.toygry.routinmoa.routine.adapter.out.persistence.entity.RoutineEntity */update routines 
    set
        completed_count=?,
        created_at=?,
        end_date=?,
        goal_count=?,
        is_deleted=?,
        is_success=?,
        name=?,
        start_date=?,
        updated_at=?,
        user_id=? 
    where
        id=?

 

update 한번 동작

 

(2) save 끈 경우 (더티 체킹)

[Hibernate] 
    select
        re1_0.id,
        re1_0.completed_count,
        re1_0.created_at,
        re1_0.end_date,
        re1_0.goal_count,
        re1_0.is_deleted,
        re1_0.is_success,
        re1_0.name,
        re1_0.start_date,
        re1_0.updated_at,
        re1_0.user_id 
    from
        routines re1_0 
    where
        re1_0.id=?
[Hibernate] 
    select
        ue1_0.id,
        ue1_0.created_at,
        ue1_0.email,
        ue1_0.level,
        ue1_0.name,
        ue1_0.points 
    from
        users ue1_0 
    where
        ue1_0.id=?
[Hibernate] 
    /* update
        for com.example.toygry.routinmoa.routine.adapter.out.persistence.entity.RoutineEntity */update routines 
    set
        completed_count=?,
        created_at=?,
        end_date=?,
        goal_count=?,
        is_deleted=?,
        is_success=?,
        name=?,
        start_date=?,
        updated_at=?,
        user_id=? 
    where
        id=?

 

동일하게 update 한번동작

 

 

오 똑똑하게 알아서 한번만 동작한다 와 ~

반응형
Comments