diff --git a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeBuilder.java b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeBuilder.java index 6e7b7e660..7e87e4e76 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeBuilder.java +++ b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeBuilder.java @@ -70,6 +70,8 @@ public class SqlTreeBuilder { private final boolean disableLazyLoad; + private final SpiQuery.TemporalMode temporalMode; + private SqlTreeNode rootNode; /** @@ -85,7 +87,7 @@ public class SqlTreeBuilder { this.subQuery = false; this.queryDetail = queryDetail; this.predicates = predicates; - + this.temporalMode = SpiQuery.TemporalMode.CURRENT; this.includeJoin = null; this.manyWhereJoins = null; this.alias = null; @@ -104,6 +106,7 @@ public class SqlTreeBuilder { this.rawNoId = false; this.desc = request.getBeanDescriptor(); this.query = request.getQuery(); + this.temporalMode = SpiQuery.TemporalMode.of(query); this.disableLazyLoad = query.isDisableLazyLoading(); this.subQuery = Type.SUBQUERY.equals(query.getType()) || Type.ID_LIST.equals(query.getType()); this.includeJoin = query.getM2mIncludeJoin(); @@ -278,13 +281,13 @@ public class SqlTreeBuilder { // Optional many property for lazy loading query BeanPropertyAssocMany lazyLoadMany = (query == null) ? null : query.getLazyLoadMany(); boolean withId = !rawNoId && !subQuery && (query == null || query.isWithId()); - return new SqlTreeNodeRoot(desc, props, myList, withId, includeJoin, lazyLoadMany, SpiQuery.TemporalMode.of(query), disableLazyLoad); + return new SqlTreeNodeRoot(desc, props, myList, withId, includeJoin, lazyLoadMany, temporalMode, disableLazyLoad); } else if (prop instanceof BeanPropertyAssocMany) { - return new SqlTreeNodeManyRoot(prefix, (BeanPropertyAssocMany) prop, props, myList, disableLazyLoad); + return new SqlTreeNodeManyRoot(prefix, (BeanPropertyAssocMany) prop, props, myList, temporalMode, disableLazyLoad); } else { - return new SqlTreeNodeBean(prefix, prop, props, myList, disableLazyLoad); + return new SqlTreeNodeBean(prefix, prop, props, myList, temporalMode, disableLazyLoad); } } diff --git a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java index bfd69c980..38f34394b 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java +++ b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java @@ -89,9 +89,9 @@ class SqlTreeNodeBean implements SqlTreeNode { * Construct for leaf node. */ SqlTreeNodeBean(String prefix, BeanPropertyAssoc beanProp, SqlTreeProperties props, - List myChildren, boolean disableLazyLoad) { + List myChildren, SpiQuery.TemporalMode temporalMode, boolean disableLazyLoad) { - this(prefix, beanProp, beanProp.getTargetDescriptor(), props, myChildren, true, null, SpiQuery.TemporalMode.CURRENT, disableLazyLoad); + this(prefix, beanProp, beanProp.getTargetDescriptor(), props, myChildren, true, null, temporalMode, disableLazyLoad); } /** @@ -544,7 +544,7 @@ class SqlTreeNodeBean implements SqlTreeNode { public SqlJoinType appendFromBaseTable(DbSqlContext ctx, SqlJoinType joinType) { SqlJoinType sqlJoinType = appendFromAsJoin(ctx, joinType); - if (desc.isSoftDelete()) { + if (temporalMode != SpiQuery.TemporalMode.SOFT_DELETED && desc.isSoftDelete()) { // add the soft delete predicate to the join clause ctx.append("and ").append(desc.getSoftDeletePredicate(ctx.getTableAlias(prefix))).append(" "); } diff --git a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeManyRoot.java b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeManyRoot.java index b2691c3d9..002f077bf 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeManyRoot.java +++ b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeManyRoot.java @@ -1,6 +1,7 @@ package com.avaje.ebeaninternal.server.query; import com.avaje.ebean.bean.EntityBean; +import com.avaje.ebeaninternal.api.SpiQuery; import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany; import com.avaje.ebeaninternal.server.deploy.DbReadContext; import com.avaje.ebeaninternal.server.deploy.DbSqlContext; @@ -12,8 +13,9 @@ final class SqlTreeNodeManyRoot extends SqlTreeNodeBean { private final BeanPropertyAssocMany manyProp; - SqlTreeNodeManyRoot(String prefix, BeanPropertyAssocMany prop, SqlTreeProperties props, List myList, boolean disableLazyLoad) { - super(prefix, prop, props, myList, disableLazyLoad); + SqlTreeNodeManyRoot(String prefix, BeanPropertyAssocMany prop, SqlTreeProperties props, List myList, + SpiQuery.TemporalMode temporalMode, boolean disableLazyLoad) { + super(prefix, prop, props, myList, temporalMode, disableLazyLoad); this.manyProp = prop; } diff --git a/src/test/java/com/avaje/tests/softdelete/TestSoftDeleteBasic.java b/src/test/java/com/avaje/tests/softdelete/TestSoftDeleteBasic.java index 8146b2ada..2d4f017a3 100644 --- a/src/test/java/com/avaje/tests/softdelete/TestSoftDeleteBasic.java +++ b/src/test/java/com/avaje/tests/softdelete/TestSoftDeleteBasic.java @@ -5,6 +5,7 @@ import com.avaje.ebean.Ebean; import com.avaje.ebean.Query; import com.avaje.ebean.SqlQuery; import com.avaje.ebean.SqlRow; +import com.avaje.tests.model.softdelete.EBasicSDChild; import com.avaje.tests.model.softdelete.EBasicSoftDelete; import org.avaje.ebeantest.LoggedSqlCollector; import org.junit.Test; @@ -231,4 +232,33 @@ public class TestSoftDeleteBasic extends BaseTestCase { } assertThat(found).isNotNull(); } + + @Test + public void testFetchWithIncludeSoftDeletes() { + + EBasicSoftDelete bean = new EBasicSoftDelete(); + bean.setName("fetchWithInclude"); + bean.addChild("child1", 91); + bean.addChild("child2", 92); + + Ebean.save(bean); + + EBasicSDChild child0 = bean.getChildren().get(0); + + EBasicSDChild upd = new EBasicSDChild(); + upd.setId(child0.getId()); + upd.setDeleted(true); + Ebean.update(upd); + + Query query = Ebean.find(EBasicSoftDelete.class) + .fetch("children") + .setIncludeSoftDeletes() + .where().eq("name", "fetchWithInclude") + .query(); + + List top = query.findList(); + assertThat(top).hasSize(1); + assertThat(top.get(0).getChildren()).hasSize(2); + + } }