Spring
Spring delete 메소드 주의사항
AlgoPoolJa
2023. 2. 14. 22:33
Delete 쿼리 종류
TL;DR
- 속도 측면에서는 deleteAllInBatch() 가 가장 빠르다.
- test 코드를 제외하고는 deleteAllInBatch() 를 사용하지 말자
설명
delete(entity)
해당 메서드는 CrudRepository 에 등록되어 있는 메서드 입니다. 엔티티를 파라미터로 받아 해당 엔티티를 삭제합니다.
deleteAll()
해당 메서드는 CrudRepository 에 등록되어 있는 메서드로 해당 레포지토리에서 관리 되는 모든 entity 를 삭제합니다.
deleteAllInBatch()
해당 메서드는 JpaRepository 에 등록되어 있는 메서드로 모든 entity 를 한번의 함수 실행으로 삭제합니다.
예시
코드의 예시로 설명해보겠습니다.
예시로 다룰 엔티티는 Member 로 다음과 같습니다.
@Where(clause = "deleted_at is null")
@SQLDelete(sql = "update member set deleted_at = now() where id = ?")
@Entity
class Member(
@Column(name = "name")
val name: String,
) {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private val id: Long? = null
@Column(name = "deleted_at")
private val deletedAt: String? = null
}
@SpringBootTest
@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL)
class MemberRepositoryTest(
val memberRepository: MemberRepository,
) {
@Test
@DisplayName("멤버 삭제")
fun deleteMember() {
println("---------------------MemberSave START---------------------")
val member = memberRepository.save(MemberFactory.of("test"))
val member2 = memberRepository.save(MemberFactory.of("test"))
val member3 = memberRepository.save(MemberFactory.of("test"))
println("---------------------MemberSave END---------------------")
println("---------------------Member DELETE START---------------------")
memberRepository.delete(member)
println("---------------------Member DELETE END---------------------")
println("---------------------Member DELETE ALL START---------------------")
memberRepository.deleteAll()
println("---------------------Member DELETE ALL END---------------------")
println("---------------------Member DELETE ALL IN BATCH START---------------------")
memberRepository.deleteAllInBatch()
println("---------------------Member DELETE ALL IN BATCH END---------------------")
}
}
---------------------MemberSave START---------------------
Hibernate:
insert
into
member
(deleted_at, name)
values
(?, ?)
Hibernate:
insert
into
member
(deleted_at, name)
values
(?, ?)
Hibernate:
insert
into
member
(deleted_at, name)
values
(?, ?)
---------------------MemberSave END---------------------
---------------------Member DELETE START---------------------
Hibernate:
select
member0_.id as id1_0_0_,
member0_.deleted_at as deleted_2_0_0_,
member0_.name as name3_0_0_
from
member member0_
where
member0_.id=?
and (
member0_.deleted_at is null
)
Hibernate:
update
member
set
deleted_at = now()
where
id = ?
---------------------Member DELETE END---------------------
---------------------Member DELETE ALL START---------------------
Hibernate:
select
member0_.id as id1_0_,
member0_.deleted_at as deleted_2_0_,
member0_.name as name3_0_
from
member member0_
where
(
member0_.deleted_at is null
)
Hibernate:
update
member
set
deleted_at = now()
where
id = ?
Hibernate:
update
member
set
deleted_at = now()
where
id = ?
---------------------Member DELETE ALL END---------------------
---------------------Member DELETE ALL IN BATCH START---------------------
Hibernate:
delete
from
member
---------------------Member DELETE ALL IN BATCH END---------------------
코드의 결과를 살펴보면 delete(entity) 와 deleteAll() 는 soft delete 가 잘 작동하는 것을 확인할 수 있습니다. 또한 deleteAll() 은 하나의 레코드마다 하나의 update 쿼리가 생성되는것을 확인할 수 있습니다. 하지만 deleteAllInBatch() 는 모든 레코드는 hard delete 하는것을 확인할 수 있습니다.
따라서 속도를 위해 deleteAllInBatch() 를 사용할 수 있지만 비즈니스 로직에서 쓰는것은 hard delete 할 일이 아닌 이상 매우 경계하면서 사용해야 합니다.