From 6108ef484b722f93ba885a4ee7cf6622f6840528 Mon Sep 17 00:00:00 2001 From: Robin Bygrave Date: Mon, 25 Jul 2016 23:31:02 +1200 Subject: [PATCH] #782 - History Many-To-Many Lazy-Loads fail --- .../com/avaje/ebeaninternal/api/SpiQuery.java | 10 ++++++++++ .../server/deploy/BeanProperty.java | 7 +++++++ .../server/query/CQueryBuilder.java | 3 +-- .../server/query/SqlTreeNodeBean.java | 3 +++ .../server/query/SqlTreeNodeRoot.java | 16 ++++++++++++++++ .../server/querydefn/DefaultOrmQuery.java | 10 ++++++++++ 6 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/avaje/ebeaninternal/api/SpiQuery.java b/src/main/java/com/avaje/ebeaninternal/api/SpiQuery.java index e0585a557..8b4ebffa0 100644 --- a/src/main/java/com/avaje/ebeaninternal/api/SpiQuery.java +++ b/src/main/java/com/avaje/ebeaninternal/api/SpiQuery.java @@ -222,6 +222,16 @@ public interface SpiQuery extends Query { */ Timestamp getAsOf(); + /** + * Return true if the base table is using history. + */ + boolean isAsOfBaseTable(); + + /** + * Set when the base table is using history. + */ + void setAsOfBaseTable(); + /** * Increment the counter of tables used in 'As Of' query. */ diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanProperty.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanProperty.java index fb888d34b..6d7bc7f2b 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanProperty.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanProperty.java @@ -1173,6 +1173,13 @@ public class BeanProperty implements ElPropertyValue, Property { return excludedFromHistory; } + /** + * Return true if this is a ManyToMany with history support (on the intersection table). + */ + public boolean isManyToManyWithHistory() { + return !excludedFromHistory && descriptor.isHistorySupport(); + } + /** * Return true if this property only exists on the draft table. */ diff --git a/src/main/java/com/avaje/ebeaninternal/server/query/CQueryBuilder.java b/src/main/java/com/avaje/ebeaninternal/server/query/CQueryBuilder.java index 9143c19e2..fafdb94bc 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/query/CQueryBuilder.java +++ b/src/main/java/com/avaje/ebeaninternal/server/query/CQueryBuilder.java @@ -472,8 +472,7 @@ public class CQueryBuilder { hasWhere = true; } - int asOfCount = query.getAsOfTableCount(); - if (asOfCount > 0 && !historySupport.isStandardsBased()) { + if (query.isAsOfBaseTable() && !historySupport.isStandardsBased()) { hasWhere = appendWhere(hasWhere, sb); sb.append(historySupport.getAsOfPredicate(request.getBaseTableAlias())); } 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 9a78a3e40..60d1e882f 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java +++ b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java @@ -507,6 +507,9 @@ public class SqlTreeNodeBean implements SqlTreeNode { if (desc.isHistorySupport()) { query.incrementAsOfTableCount(); } + if (lazyLoadParent != null && lazyLoadParent.isManyToManyWithHistory()) { + query.incrementAsOfTableCount(); + } if (intersectionAsOfTableAlias) { query.incrementAsOfTableCount(); } diff --git a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeRoot.java b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeRoot.java index 8e68afb8d..75cd58059 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeRoot.java +++ b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeRoot.java @@ -33,6 +33,22 @@ public final class SqlTreeNodeRoot extends SqlTreeNodeBean { this.includeJoin = null; } + /** + * Set AsOf support (at root level). + */ + public void addAsOfTableAlias(SpiQuery query) { + if (desc.isHistorySupport()) { + query.setAsOfBaseTable(); + query.incrementAsOfTableCount(); + } + if (lazyLoadParent != null && lazyLoadParent.isManyToManyWithHistory()) { + query.incrementAsOfTableCount(); + } + for (int i = 0; i < children.length; i++) { + children[i].addAsOfTableAlias(query); + } + } + /** * For the root node there is no join type or on clause etc. */ diff --git a/src/main/java/com/avaje/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/src/main/java/com/avaje/ebeaninternal/server/querydefn/DefaultOrmQuery.java index d8731b717..befb221ce 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/querydefn/DefaultOrmQuery.java +++ b/src/main/java/com/avaje/ebeaninternal/server/querydefn/DefaultOrmQuery.java @@ -146,6 +146,8 @@ public class DefaultOrmQuery implements SpiQuery { private DefaultExpressionList havingExpressions; + private boolean asOfBaseTable; + private int asOfTableCount; /** @@ -280,6 +282,14 @@ public class DefaultOrmQuery implements SpiQuery { return softDeletePredicates; } + public boolean isAsOfBaseTable() { + return asOfBaseTable; + } + + public void setAsOfBaseTable() { + this.asOfBaseTable = true; + } + @Override public void incrementAsOfTableCount() { asOfTableCount++;