From abcc651e7fad54e42300f09fef6f1fb0b84ef934 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 9 Feb 2018 15:00:58 +1300 Subject: [PATCH] #1253 - Query where many isNotEmpty() ... on ManyToMany with SoftDelete produces incorrect SQL Fix --- .../server/deploy/BeanPropertyAssocMany.java | 20 +++++++++++++++---- .../server/deploy/TableJoin.java | 13 +++++++++++- .../server/query/CQueryBuilder.java | 2 +- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java index 78077bafd..1a04e8ef9 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java @@ -465,22 +465,34 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc { @Override public String getAssocIsEmpty(SpiExpressionRequest request, String path) { - StringBuilder sb = new StringBuilder(); + boolean softDelete = targetDescriptor.isSoftDelete(); + + StringBuilder sb = new StringBuilder(50); SpiQuery query = request.getQueryRequest().getQuery(); if (manyToMany) { sb.append(query.isAsDraft() ? intersectionDraftTable : intersectionPublishTable); } else { sb.append(targetDescriptor.getBaseTable(query.getTemporalMode())); } - sb.append(" x where "); + if (softDelete && manyToMany) { + sb.append(" x join "); + sb.append(targetDescriptor.getBaseTable(query.getTemporalMode())); + sb.append(" x2 on "); + inverseJoin.addJoin("x2", "x", sb); + } else { + sb.append(" x"); + } + + sb.append(" where "); for (int i = 0; i < exportedProperties.length; i++) { if (i > 0) { sb.append(" and "); } exportedProperties[i].appendWhere(sb, "x.", path); } - if (targetDescriptor.isSoftDelete()) { - sb.append(" and ").append(targetDescriptor.getSoftDeletePredicate("x")); + if (softDelete) { + String alias = (manyToMany) ? "x2" : "x"; + sb.append(" and ").append(targetDescriptor.getSoftDeletePredicate(alias)); } return sb.toString(); } diff --git a/src/main/java/io/ebeaninternal/server/deploy/TableJoin.java b/src/main/java/io/ebeaninternal/server/deploy/TableJoin.java index 5f6f91fff..6a23e300d 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/TableJoin.java +++ b/src/main/java/io/ebeaninternal/server/deploy/TableJoin.java @@ -1,9 +1,9 @@ package io.ebeaninternal.server.deploy; +import io.ebean.util.SplitName; import io.ebeaninternal.server.core.InternString; import io.ebeaninternal.server.deploy.meta.DeployTableJoin; import io.ebeaninternal.server.deploy.meta.DeployTableJoinColumn; -import io.ebean.util.SplitName; import io.ebeaninternal.server.query.SqlJoinType; /** @@ -145,4 +145,15 @@ public final class TableJoin { return joinType.autoToOuter(type); } + public void addJoin(String a1, String a2, StringBuilder sb) { + for (int i = 0; i < columns.length; i++) { + TableJoinColumn pair = columns[i]; + if (i > 0) { + sb.append(" and "); + } + sb.append(a1).append(".").append(pair.getLocalDbColumn()); + sb.append(" = "); + sb.append(a2).append(".").append(pair.getForeignDbColumn()); + } + } } diff --git a/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java b/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java index 24e793666..5753d4021 100644 --- a/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java +++ b/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java @@ -609,7 +609,7 @@ class CQueryBuilder { if (!hasWhere) { sb.append(" where "); } else { - sb.append("and "); + sb.append(" and "); } for (int i = 0; i < softDeletePredicates.size(); i++) { if (i > 0) {