From 021d57f4b2efacb16c7693985cfaa147dca954d7 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Thu, 1 Mar 2018 23:43:08 +0100 Subject: [PATCH] FIX: @Formula on @ManyToOne produces SQLException ... fix appends missing FROM clause for formula joins #1299 --- .../server/query/SqlTreeNodeBean.java | 5 ++- .../server/query/SqlTreeNodeExtraJoin.java | 4 ++ .../org/tests/family/TestInheritance.java | 42 +++++++++++++++++++ .../tests/model/family/GrandParentPerson.java | 16 ++++++- .../org/tests/model/family/ParentPerson.java | 2 +- 5 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java b/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java index 22a3be01d..3d16f8ff2 100644 --- a/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java +++ b/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java @@ -531,7 +531,10 @@ class SqlTreeNodeBean implements SqlTreeNode { */ @Override public void appendFrom(DbSqlContext ctx, SqlJoinType joinType) { - + if (nodeBeanProp != null && nodeBeanProp.isFormula()) { + // add joins for formula beans + nodeBeanProp.appendFrom(ctx, joinType); + } ctx.pushJoin(prefix); ctx.pushTableAlias(prefix); diff --git a/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeExtraJoin.java b/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeExtraJoin.java index d6d642166..ba83d4ced 100644 --- a/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeExtraJoin.java +++ b/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeExtraJoin.java @@ -126,6 +126,10 @@ class SqlTreeNodeExtraJoin implements SqlTreeNode { joinType = SqlJoinType.OUTER; } if (!manyToMany) { + if (assocBeanProperty.isFormula()) { + // add joins for formula beans + assocBeanProperty.appendFrom(ctx, joinType); + } joinType = assocBeanProperty.addJoin(joinType, prefix, ctx); } diff --git a/src/test/java/org/tests/family/TestInheritance.java b/src/test/java/org/tests/family/TestInheritance.java index 3246d2d0c..de4ea30d5 100644 --- a/src/test/java/org/tests/family/TestInheritance.java +++ b/src/test/java/org/tests/family/TestInheritance.java @@ -219,4 +219,46 @@ public class TestInheritance extends BaseTestCase { assertEquals("Munich", grandparent1.getAddress()); assertEquals(1, grandparent1.getEffectiveBean().getId().intValue()); } + + @Test + public void testFindCount() { + EBasic basicA = new EBasic(); + basicA.setName("FamilyName A"); + basicA.setDescription("Description A"); + server().save(basicA); + + EBasic basicB = new EBasic(); + basicB.setName("FamilyName B"); + basicB.setDescription("Description B"); + server().save(basicB); + + + GrandParentPerson gp1 = new GrandParentPerson(); + gp1.setFamilyName("FamilyName A"); + gp1.setName("Franz"); + server().save(gp1); + + gp1 = server().find(GrandParentPerson.class).where().eq("name", "Franz").findOne(); + assertEquals("FamilyName A", gp1.getFamilyName()); + assertEquals("Description A", gp1.getBasicSameName().getDescription()); + + + gp1 = server().find(GrandParentPerson.class).where().eq("basicSameName.name", "FamilyName A").findOne(); + assertEquals("FamilyName A", gp1.getFamilyName()); + assertEquals("Description A", gp1.getBasicSameName().getDescription()); + + + gp1 = server().find(GrandParentPerson.class).where().eq("basicSameName.description", "Description A").findOne(); + assertEquals("FamilyName A", gp1.getFamilyName()); + assertEquals("Description A", gp1.getBasicSameName().getDescription()); + + int count; + count = server().find(GrandParentPerson.class).where().eq("name", "Franz").findCount(); + assertEquals(1, count); + count = server().find(GrandParentPerson.class).where().eq("basicSameName.name", "FamilyName A").findCount(); + assertEquals(1, count); + count = server().find(GrandParentPerson.class).where().eq("basicSameName.description", "Description A").findCount(); + assertEquals(1, count); + + } } diff --git a/src/test/java/org/tests/model/family/GrandParentPerson.java b/src/test/java/org/tests/model/family/GrandParentPerson.java index 4246290b6..9ea2c97a2 100644 --- a/src/test/java/org/tests/model/family/GrandParentPerson.java +++ b/src/test/java/org/tests/model/family/GrandParentPerson.java @@ -5,6 +5,7 @@ import org.tests.model.basic.EBasic; import javax.persistence.CascadeType; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.OrderBy; @@ -22,7 +23,7 @@ public class GrandParentPerson extends InheritablePerson { // This rather complex formulas should be built later by CustomAnnotationParser private static final String PARENT_PERSON_AGGREGATE_JOIN = "left join " + "(select i1.parent_identifier, count(*) as child_count, sum(i1.age) as child_age from parent_person i1 group by i1.parent_identifier) " - + "as f1 on f1.parent_identifier = ${ta}.identifier"; + + "f1 on f1.parent_identifier = ${ta}.identifier"; //@Count("children") @Formula(select = "coalesce(f1.child_count, 0)", join = PARENT_PERSON_AGGREGATE_JOIN) @@ -37,6 +38,11 @@ public class GrandParentPerson extends InheritablePerson { private String address; + @ManyToOne(optional = true, fetch = FetchType.EAGER) + @Formula(select = "f3.id", join = "left join e_basic f3 on f3.name = ${ta}.family_name") + private EBasic basicSameName; + + // Demonstrate formula usage @Formula(select = "coalesce(${ta}.some_bean_id,1)") @ManyToOne @@ -78,4 +84,12 @@ public class GrandParentPerson extends InheritablePerson { public EBasic getEffectiveBean() { return effectiveBean; } + + public EBasic getBasicSameName() { + return basicSameName; + } + + public void setBasicSameName(EBasic basicSameName) { + this.basicSameName = basicSameName; + } } diff --git a/src/test/java/org/tests/model/family/ParentPerson.java b/src/test/java/org/tests/model/family/ParentPerson.java index 97472ef7b..242721993 100644 --- a/src/test/java/org/tests/model/family/ParentPerson.java +++ b/src/test/java/org/tests/model/family/ParentPerson.java @@ -19,7 +19,7 @@ public class ParentPerson extends InheritablePerson { //This rather complex formulas should be built later by CustomAnnotationParser private static final String CHILD_PERSON_AGGREGATE_JOIN = "left join " + "(select i2.parent_identifier, count(*) as child_count, sum(i2.age) as child_age from child_person i2 group by i2.parent_identifier) " - + "as f2 on f2.parent_identifier = ${ta}.identifier"; + + "f2 on f2.parent_identifier = ${ta}.identifier"; private static final String GRAND_PARENT_PERSON_JOIN = "join grand_parent_person j1 on j1.identifier = ${ta}.parent_identifier";