๋ค์ด๊ฐ๋ฉฐ
DB๋ฅผ ๋ง๋ค๋ฉด์ ์ฐ๋ฆฌ๋ ์ญ์ ํ๋ ๋ฐฉ๋ฒ์ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค.
๋ฐฉ์ | ์ค๋ช |
Soft Delete | `UPDATE table SET delete = 1 WHERE id = 2` ํํ๋ก ROW๊ฐ ์ญ์ ๋์ง ์๊ณ flag๋ฅผ ํตํ ์ ์ด ํ๋ ๋ฐฉ์ |
Hard Delete | DELETE FROM table WHERE id = 2 ํํ๋ก ROW๊ฐ ์ค์ ๋ก ์ญ์ ๋๋ ๋ฐฉ์ |
`Hard Delete`๋ฅผ ํ๋ ๊ฒฝ์ฐ๋ ์์ง๋ง, `Soft Delete`๋ฅผ ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ ๋ง๋ค.
์ด๋ฐ ๊ฒฝ์ฐ์ JPA Entity Graph ์ ๊ฒฝ์ฐ๋ `Soft Delete`์ ๋ฐ์ดํฐ๊ฐ ๊ฐ์ด ๋ด๊ฒจ์ ์จ๋ค.
`Application level์์ ํํฐ ํ๋ฉด ๋๋๊ฑฐ ์๋๋? ` ๋ผ๊ณ ์๊ฐ ํ ์ ์์ง๋ง, ์ธ๊ฐ์ด๊ธฐ ๋๋ฌธ์ ๋ก์ง์ ๊ตฌ๋ฉ์ด ๋ง์ด ์๊ธธ ์ ์๋ค.
์ค๋์ JPA์์ Soft Delete๋ฅผ ๋์ฑ ํธํ๊ฒ ํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์ด์ผ๊ธฐ ํด๋ณด๋ ค๊ณ ํ๋ค.
@Where Annotation
https://docs.jboss.org/hibernate/orm/5.4/javadocs/org/hibernate/annotations/Where.html
" Where clause to add to the element Entity or target entity of a collection. The clause is written in SQL. A common use case here is for soft-deletes."
@Where ์ด๋ ธํ ์ด์ ์ Entity์ Default ์กฐ๊ฑด์ ์ง์ ํ ์ ์๋ ์ด๋ ธํ ์ด์ ์ด๋ค.
์ฅ์ ์ 'Soft Delete'๋ก ์ธํ์ฌ, ๊ฐ์ฒด ๊ทธ๋ํ์์ ๋ฐ์ ํ ์ ์๋ ๋ฌธ์ ๋ฅผ ์ ๊ฒฝ์ฐ์ง ์์๋ ๋๋ค.
๋ํ,@OneToMany, @ManyToOne ๋ฑ์ ์กฐ์ธ์ด ๊ฑธ๋ฆฐ ๊ฒฝ์ฐ์๋ ๋ฐ๋ก ์ฟผ๋ฆฌ ์กฐ๊ฑด์ ์ง์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ํธํด์ง๋ค.
๋จ์ ์, ๋ฌด์กฐ๊ฑด ์กฐ๊ฑด์ด ์ ์ฉ ๋๊ธฐ ๋๋ฌธ์, ์ญ์ ๋ ๊ฑธ ๊ฐ์ ธ์์ผ ํ๋ ์ํฉ์๋ ๋ ์ ๋งคํด์ง๋ค.
(์ด ๊ฒฝ์ฐ๋ @FilterDef์ ํ์ฉํ๋ฉด ๋๋ค๊ณ ํ๋๋ฐ, ์กฐ๋ง๊ฐ ๋ฐ๋ก ๋ค๋ค๋ณผ๋ ค๊ณ ํ๋ค)
(๊ทธ๋ฆฌ๊ณ ๊ฐ์ธ์ ์ผ๋ก ์ญ์ ์ ๋ํ๊ฑธ ๋ค์ ๊ฐ์ ธ์ค๋ ๊ฒ๋ ๋ชจ์ ์๋๊น.. ์ถ์๋ฐ..)
์๋ฅผ ๋ค์ด ์๋์ ๊ฐ์ Entity๊ฐ ์๋ค๋ ๊ฐ์ ์ ํด๋ณด์.
@Entity
@Where("del=0")
class Product(
var name: String,
val del: Boolean = false
) {
@Id
@GeneratedValue
var id: Long? = null
protected set
@ManyToOne
val image: Image? = null
fun expire() {
this.del = true
}
}
์ด ๋ฐ์ดํฐ๊ฐ id=1 ์ด๊ณ , del=true ์ํฉ์ด๋ผ๋ฉด, productRepository.findById(1) ๋ก ์กฐํ์ ๋ฐ์ดํฐ๊ฐ ์๋ค๊ณ ๋ฐํ ๋๊ฒ ๋๋ค.
@SQLDelete Annotation
์กฐํ๋ฅผ ํ ๋๋ ๊ธฐ๋ณธ์ ์ธ ์กฐ๊ฑด์ด ๋ถ์๊ธฐ ๋๋ฌธ์ ๋ฌด๋ฆฌ ์์ด ์ฌ์ฉ ํ ์ ์๋ค.
ํ์ง๋ง ์ธ๊ฐ์ ์์ฌ์ ๋์ด ์๊ธฐ ๋๋ฌธ์, ์ญ์ ๊ฐ ๋ ๋๋ flag๋ฅผ ์ง์ ๋ณ๊ฒฝ ํ๋ ๊ฒ์ด ์๋ ORM Level์์ ์ง์์ ํด์คฌ์ผ๋ฉด ์ข๊ฒ ๋ค ๋ผ๋ ์๊ฐ์ด ๋ค๊ธฐ ์์ํ๋ค. ๊ทธ๊ฒ์ ํด๊ฒฐ ํ๊ธฐ ์ํด ๋์จ๊ฒ์ด @SQLDelete ์ด๋ ธํ ์ด์ ์ด๋ค.
"Custom SQL statement for delete of an entity/collection."
์๋์ ์์๋ฅผ ๋ณด์
@Entity
@Where("del=0")
@SQLDelete("UPDATE product SET del=1 WHERE id = ?")
class Product(
var name: String,
val del: Boolean = false
) {
@Id
@GeneratedValue
var id: Long? = null
protected set
@ManyToOne
val image: Image? = null
}
@SQLDelete ์ด๋ ธํ ์ด์ ์ ํตํด, ์ค์ ์ญ์ ๊ฐ ์ด๋ฃจ์ด์ง๋ ์ํ ํ ์ฟผ๋ฆฌ๋ฅผ ์ ์ผ๋ฉด ๋๋ค.
๊ทธ๋ผ productRepository.deleteById(1L) ํํ๋ก ์งํ์ด ๋๋ฉด 'DELETE FROM product WHERE id = 1' ํํ๋ก ์ฟผ๋ฆฌ๊ฐ ๋์ ํ๋ ๊ฒ์ด ์๋ 'Update product SET del 1 WHERE id = 1' ํํ๋ก ์ฟผ๋ฆฌ๊ฐ ๋ฐ์๋์ด ๋์ํ๊ฒ ๋๋ค.
'๐ป ๋ฐฑ์๋ ๊ฐ๋ฐ > JPA - Hibernate' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
02. ๋น์ ์ @Transactional์ readOnly ์ต์ ์ ์ฐ๊ณ ์๋์? (3) | 2021.02.04 |
---|---|
01. ์์๋๋ฉด ์ธ๋ผ์๋ GeneratedValue ์ด์ผ๊ธฐ Part1 (250) | 2020.06.04 |
๋๊ธ