From e99db44ddf95c32ef326ba3618789c3d7ab8e3a0 Mon Sep 17 00:00:00 2001 From: Tobias Date: Tue, 7 Jul 2020 12:20:59 +0200 Subject: [PATCH] Add test for soft deleted children When a child is referenced in the query, Ebean should make sure that the child (or any of the objects connecting it in the query) is deleted. Ie. if a query requires a child to have a certain value, it should filter out those children that are soft deleted. It should also perform the deleted check on all objects leading up to that child. E.g. assuming that all objects are soft deletable, the following where(): DB.find(Alpha.class).where() .eq("alpha.beta.gamma.name", "bar") should generate a query with "t0.deleted = false AND t1.deleted = false AND t2.deleted = false AND t2.name = 'bar'" --- .../tests/softdelete/TestSoftDeleteBasic.java | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/test/java/org/tests/softdelete/TestSoftDeleteBasic.java b/src/test/java/org/tests/softdelete/TestSoftDeleteBasic.java index a63b0b5ae..529241bbc 100644 --- a/src/test/java/org/tests/softdelete/TestSoftDeleteBasic.java +++ b/src/test/java/org/tests/softdelete/TestSoftDeleteBasic.java @@ -9,11 +9,13 @@ import io.ebean.SqlRow; import io.ebean.Transaction; import org.ebeantest.LoggedSqlCollector; import org.junit.Test; +import org.tests.model.softdelete.EBasicNoSDChild; import org.tests.model.softdelete.EBasicSDChild; import org.tests.model.softdelete.EBasicSoftDelete; import java.util.List; +import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; @@ -136,6 +138,64 @@ public class TestSoftDeleteBasic extends BaseTestCase { query.delete(); } + @Test + public void testNotFindSoftDeleted() { + EBasicSoftDelete bean = new EBasicSoftDelete(); + bean.setName("Shouldn't be found with child expression when child is deleted"); + DB.save(bean); + final EBasicSDChild child = new EBasicSDChild(bean, "Delete me, don't find me", 1L); + DB.save(child); + DB.delete(child); + + Query query = DB.find(EBasicSoftDelete.class) + .where() + .eq("id", bean.getId()) + .eq("children.amount", 1L) + .query(); + + List list = query.findList(); + assertSql(query).contains("t0.deleted = false"); + // Make sure that query includes that the child mustn't've been deleted + assertSql(query).contains("t1.deleted = false"); + assertThat(list).hasSize(0); + + // Cleanup created entity + query.delete(); + DB.deleteAllPermanent(singletonList(child)); + DB.deleteAllPermanent(singletonList(bean)); + } + + @Test + public void testNotFindSoftDeletedMultilevel() { + EBasicSoftDelete bean = new EBasicSoftDelete(); + bean.setName("Shouldn't be found with child expression when child is deleted"); + DB.save(bean); + final EBasicSDChild child = new EBasicSDChild(bean, "Delete me, don't find me", 1L); + DB.save(child); + DB.delete(child); + + EBasicNoSDChild secondChild = new EBasicNoSDChild(bean, "Never deleted", 2L); + DB.save(secondChild); + + + Query query = DB.find(EBasicNoSDChild.class) + .where() + .eq("id", bean.getId()) + .eq("owner.children.amount", 1L) + .query(); + + List list = query.findList(); + // Make sure that query includes that the child mustn't've been deleted + assertSql(query).contains("t1.deleted = false"); + assertSql(query).contains("t2.deleted = false"); + assertThat(list).hasSize(0); + + // Cleanup created entity + query.delete(); + DB.deleteAllPermanent(singletonList(child)); + DB.deleteAllPermanent(singletonList(bean)); + } + @Test public void testDeleteById_and_findCount() {