Soft Delete — Silinen Hesap Gerçekten Gitti mi?
Önce şunu oku: Toplu UPDATE — Veritabanı Değişti, Nesnen Neden Haberi Yok?
30 saniyede özet
Bankada bir kaydı gerçekten silmek çoğu zaman yasaktır: denetçi yıllar sonra sorabilir. Soft delete satırı silmek yerine işaretler. Ama işaret her sorguda süzülmezse silinen satır geri gelir, benzersiz indeksler de eski satıra takılır.
Bir kütüphane, rafından kaldırdığı kitapları çöpe atmaz; üstüne “kaldırıldı” etiketi yapıştırır. Katalog bilgisayarı etiketli kitapları göstermez. Ama rafa doğrudan bakan biri, o kitabı hâlâ orada görür.
-
Bayt: Müşteri TR01 hesabını kapattı. Silmek yerine deleted = true yaptık, denetim için kalsın!
-
Sen: Ama aktif hesaplar listesinde TR01 hâlâ görünüyor. Gece raporu da onu sayıyor.
-
Bayt: Bir de aynı IBAN'la yeni hesap açılamıyor...
-
Bayt: Satırı işaretledik ama işareti kimin okuduğuna bakmadık. Bir bakalım.
Neden silmiyoruz?
Bankalar kapanan bir hesabın bilgisini yıllarca saklamak zorundadır; denetçi ya da mahkeme sorabilir. Satırı DELETE ile silmek bu bilgiyi geri dönülmez biçimde yok eder.
soft deleteSatırı silmek yerine deleted gibi bir alanla işaretleyip uygulamada gizlemek. Bilgi denetim için tabloda kalır.Sözlükte gör →, satırı silmek yerine deleted = true gibi bir alanla işaretlemektir. Satır tabloda kalır; uygulama onu “yokmuş gibi” davranarak gizler.
Kafam karıştı, daha basit anlat
Soft delete: satırı silme, işaretle. Bilgi kalır, ekranda görünmez.
Soft delete nedir?
Bir bankada kapanan hesabı DELETE ile silmenin sakıncası nedir?
İşareti kim okur?
Hesap varlığının üstünde @SQLRestriction("deleted = false") var. Gece raporu ise native SQL ile SELECT * FROM account yapıyor. Kapanan hesap raporda görünür mü? Cevabı göster
Görünür. @SQLRestriction yalnızca Hibernate’in kendi yazdığı sorgulara, yani varlık yüklemelerine ve JPQL/HQL sorgularına eklenir. Native SQL’i Hibernate yazmaz; koşulu raporun kendisi eklemelidir.
Adım adım oku
- Kitabı atmak: arşiv için de gider.
- "Kaldırıldı" etiketi: kitap rafta kalır.
- Katalog gizler, rafa doğrudan bakan görür.
- Etiket yetmez: herkes kataloğa bakmalı.
İşareti her sorguda elle süzmek, unutulan her sorguda silinen satırı geri getirir. Hibernate’in @SQLRestriction notası filtreyi varlığın üstüne koyar ve Hibernate’in yazdığı her sorguya kendisi ekler. Ama Hibernate’in yazmadığı bir native SQLHibernate'in değil, doğrudan senin yazdığın SQL. Varlığa konan filtreler ve bazı Hibernate özellikleri ona uygulanmaz.Sözlükte gör → sorgusu bu filtreyi görmez.
Bir sorun daha var: silinen satır tabloda kaldığı için IBAN üzerindeki benzersiz indekste yer tutmaya devam eder. Çözüm, yalnızca silinmemiş satırları kapsayan bir kısmi indeksYalnızca bir koşulu sağlayan satırları kapsayan indeks, örneğin WHERE deleted = false. Benzersizliği canlı satırlarla sınırlamak için kullanılır.Sözlükte gör →tir.
Kafam karıştı, daha basit anlat
Filtreyi varlığa koy; native SQL’de kendin yaz. Benzersizliği yalnızca canlı satırlara uygula.
@SQLRestriction("deleted = false") ne yapar?
Kapanan hesabın IBAN'ıyla yeni hesap açılamıyor. Neden?
Kendin gör
Silinen hesap gerçekten gitti mi?
Tohum 859859Oynat ya da adımla: her adımda bir durum yaşanır.
Şu an ne oldu?
deleted = true (filtre sorgularda)
Müşteri TR01 hesabını kapattı. Dört durum yaşanacak.
Görevler0/3
Kapanan hesabı aktif listede gösteraçık
İpucu
Varsayılan ayarlar yeter.
Aynı IBAN’la yeni hesap açarken çakışaçık
İpucu
Silinen satır tabloda kalsın.
Hibernate sorgularını koru ama native raporu kaçıraçık
İpucu
Filtreyi varlığa koy, indeksi düzelt.
Olay günlüğü (0)
Henüz olay yok. Oynat veya adımla.
- Varsayılanla oynat. Elle yazılan filtre: kapanan hesap aktif listede göründü, yeni hesap IBAN’a takıldı, gece raporu onu saydı.
- “@SQLRestriction” seç. Liste düzeldi; ama IBAN çakışması ve native rapor sorunu sürdü.
- “Kısmi benzersiz indeks”i aç. IBAN yeniden kullanılabildi; geriye yalnızca native rapor kaldı.
- “DELETE” seç. Her şey temiz görünüyor, ama denetçiye verecek bilgi kalmadı.
Kısmi benzersiz indeks (UNIQUE ... WHERE deleted = false) neyi çözer?
Gece raporu native SQL ile SELECT count(*) FROM account yapıyor. Varlıkta @SQLRestriction var. Sonuç ne olur?
Tuzaklar
Native sorguları unutmak: raporlar ve toplu işler çoğu zaman native SQL yazar. Onları deleted = false koşuluyla yaz ya da yalnızca canlı satırları gösteren bir veritabanı görünümünden oku.
Benzersiz indeksi olduğu gibi bırakmak. Silinen satır aynı IBAN’ı tutmaya devam eder. Benzersizliği WHERE deleted = false ile yalnızca canlı satırlara uygula.
Kim ve ne zaman sildi bilgisini atlamak. Yalnızca deleted = true demek, denetçinin asıl sorusunu cevaplamaz. Silme zamanını ve kimin sildiğini de sakla.
Kafam karıştı, daha basit anlat
Native SQL’de filtreyi yaz, indeksi canlı satırlara daralt, kim ve ne zaman bilgisini sakla.
Yalnızca deleted = true saklamak denetçinin hangi sorusunu cevapsız bırakır?
Aşağıdaki örnek bir bankanın hesap tablosundan: Hibernate’in silmeyi güncellemeye çevirdiği, filtreyi kendisi eklediği ve kimin sildiğini sakladığı bir varlık.
Derinleş · Kapanan hesaplar: soft delete, kısmi indeks, native rapor 4 dosya · ~55 satır · ilk okumada atlayabilirsin
Kendini sına
Soft delete satırı tablodan siler.
Filtre her repository sorgusuna elle eklenmiş ve biri yeni bir sorgu yazarken unutmuş. Ne olur?
Aklında kalacak üç şey
- 1 Soft delete satırı silmez, deleted gibi bir alanla işaretler; böylece kapanan hesabın bilgisi denetim için kalır.
- 2 İşaret her sorguda elle süzülürse unutulan her sorgu silinen satırı geri getirir. @SQLRestriction filtreyi varlığın üstüne koyar ve Hibernate'in yazdığı sorgulara kendisi ekler.
- 3 @SQLRestriction native SQL'e uygulanmaz ve silinen satır benzersiz indekste yer tutmaya devam eder. Native sorgular filtreyi kendisi yazmalı; benzersizlik kısmi bir indeksle kurulmalı.
4 kart sonraki derste seni bekliyor