Restoring rows and querying around the filter ######## H2 ######## database: H2Dialect / H2 2.4.240 (2025-09-22) == Boolean strategy: the deleted row is still in the table raw rows : [1 | kept | true, 2 | alive | false] -- HQL count sql> select count(ad1_0.id) from article_deleted ad1_0 where ad1_0.deleted=false -- native count sql> select count(*) from article_deleted == A native query mapped to the entity returns the deleted row native select * ... id=1 -> 1 entity, title=kept == HQL cannot restore: the flag is not an attribute IllegalArgumentException -> PathElementException: Could not resolve attribute 'deleted' of 'com.ankurm.softdelete.ArticleDeleted' == Native UPDATE restores it rows updated: 1 -- find after restore sql> select ad1_0.id,ad1_0.title from article_deleted ad1_0 where ad1_0.deleted=false and ad1_0.id=? == Stale persistence context: a soft delete done behind the session's back same session, row deleted by someone else: find -> still the entity (first-level cache) after session.clear(): find -> null == Timestamp strategy: restore sets the column back to NULL after delete : [1 | true] after restore : [1 | false] == @SQLRestriction: HQL CAN name the column, but the restriction rewrites the UPDATE too -- HQL: update ArticleManual a set a.deleted = false sql> update article_manual am1_0 set deleted=false where am1_0.id=? and (am1_0.deleted = false) HQL restore updated 0 rows raw rows : [1 | man | true] ######## POSTGRES ######## database: PostgreSQLDialect / PostgreSQL 17.11 == Boolean strategy: the deleted row is still in the table raw rows : [1 | kept | true, 2 | alive | false] -- HQL count sql> select count(ad1_0.id) from article_deleted ad1_0 where ad1_0.deleted=false -- native count sql> select count(*) from article_deleted == A native query mapped to the entity returns the deleted row native select * ... id=1 -> 1 entity, title=kept == HQL cannot restore: the flag is not an attribute IllegalArgumentException -> PathElementException: Could not resolve attribute 'deleted' of 'com.ankurm.softdelete.ArticleDeleted' == Native UPDATE restores it rows updated: 1 -- find after restore sql> select ad1_0.id,ad1_0.title from article_deleted ad1_0 where ad1_0.deleted=false and ad1_0.id=? == Stale persistence context: a soft delete done behind the session's back same session, row deleted by someone else: find -> still the entity (first-level cache) after session.clear(): find -> null == Timestamp strategy: restore sets the column back to NULL after delete : [1 | true] after restore : [1 | false] == @SQLRestriction: HQL CAN name the column, but the restriction rewrites the UPDATE too -- HQL: update ArticleManual a set a.deleted = false sql> update article_manual am1_0 set deleted=false where am1_0.id=? and (am1_0.deleted = false) HQL restore updated 0 rows raw rows : [1 | man | true]