Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_017ic4b7rnC7jppGGdHGESvy
68 lines
3.4 KiB
Plaintext
68 lines
3.4 KiB
Plaintext
@SoftDelete vs @SQLDelete+@SQLRestriction: bulk deletes, double deletes, converters
|
|
|
|
######## H2 ########
|
|
database: H2Dialect / H2 2.4.240 (2025-09-22)
|
|
|
|
== 1. HQL bulk delete: delete from ArticleDeleted / delete from ArticleManual
|
|
-- delete from ArticleDeleted
|
|
sql> update article_deleted ad1_0 set deleted=true where ad1_0.deleted=false
|
|
article_deleted rows: [1 | a | true, 2 | b | true]
|
|
-- delete from ArticleManual
|
|
sql> delete from article_manual am1_0 where (am1_0.deleted = false)
|
|
article_manual rows : []
|
|
|
|
== 2. Two sessions delete the same row (second one is stale)
|
|
-- @SQLDelete entity, s1.flush()
|
|
sql> update article_manual set deleted = true where id = ?
|
|
flush succeeded silently (the hand-written UPDATE has no 'and deleted = false' guard)
|
|
(the @SoftDelete entity fails the same scenario with StaleStateException: see 02-ddl-and-sql.txt)
|
|
|
|
== 3. converter attribute: char(1) 'Y'/'N' column named is_gone
|
|
create table article_yes_no (is_gone char(1) not null check ((is_gone in ('N','Y'))), id bigint generated by default as identity, title varchar(255), primary key (id));
|
|
comment on column article_yes_no.is_gone is 'Y = deleted';
|
|
alive : [1 | N]
|
|
-- remove
|
|
sql> select ayn1_0.id,ayn1_0.title from article_yes_no ayn1_0 where ayn1_0.is_gone='N' and ayn1_0.id=?
|
|
sql> update article_yes_no set is_gone='Y' where id=? and is_gone='N'
|
|
deleted : [1 | Y]
|
|
|
|
== 4. @SoftDelete on a @MappedSuperclass
|
|
create table note (deleted_at timestamp(6) with time zone, id bigint generated by default as identity, text varchar(255), primary key (id));
|
|
-- remove(note)
|
|
sql> select n1_0.id,n1_0.text from note n1_0 where n1_0.deleted_at is null and n1_0.id=?
|
|
sql> update note set deleted_at=localtimestamp where id=? and deleted_at is null
|
|
raw: [1 | true]
|
|
|
|
######## POSTGRES ########
|
|
database: PostgreSQLDialect / PostgreSQL 17.11
|
|
|
|
== 1. HQL bulk delete: delete from ArticleDeleted / delete from ArticleManual
|
|
-- delete from ArticleDeleted
|
|
sql> update article_deleted ad1_0 set deleted=true where ad1_0.deleted=false
|
|
article_deleted rows: [1 | a | true, 2 | b | true]
|
|
-- delete from ArticleManual
|
|
sql> delete from article_manual am1_0 where (am1_0.deleted = false)
|
|
article_manual rows : []
|
|
|
|
== 2. Two sessions delete the same row (second one is stale)
|
|
-- @SQLDelete entity, s1.flush()
|
|
sql> update article_manual set deleted = true where id = ?
|
|
flush succeeded silently (the hand-written UPDATE has no 'and deleted = false' guard)
|
|
(the @SoftDelete entity fails the same scenario with StaleStateException: see 02-ddl-and-sql.txt)
|
|
|
|
== 3. converter attribute: char(1) 'Y'/'N' column named is_gone
|
|
create table article_yes_no (is_gone char(1) not null check ((is_gone in ('N','Y'))), id bigint generated by default as identity, title varchar(255), primary key (id));
|
|
comment on column article_yes_no.is_gone is 'Y = deleted';
|
|
alive : [1 | N]
|
|
-- remove
|
|
sql> select ayn1_0.id,ayn1_0.title from article_yes_no ayn1_0 where ayn1_0.is_gone='N' and ayn1_0.id=?
|
|
sql> update article_yes_no set is_gone='Y' where id=? and is_gone='N'
|
|
deleted : [1 | Y]
|
|
|
|
== 4. @SoftDelete on a @MappedSuperclass
|
|
create table note (deleted_at timestamp(6) with time zone, id bigint generated by default as identity, text varchar(255), primary key (id));
|
|
-- remove(note)
|
|
sql> select n1_0.id,n1_0.text from note n1_0 where n1_0.deleted_at is null and n1_0.id=?
|
|
sql> update note set deleted_at=localtimestamp where id=? and deleted_at is null
|
|
raw: [1 | true]
|