From 4ef5abceca8bbf134d0ae05e94b396b2fbb8847e Mon Sep 17 00:00:00 2001 From: peterko2017 <33632675+peterko2017@users.noreply.github.com> Date: Tue, 4 Aug 2020 22:33:34 -0600 Subject: [PATCH] Add STI Discrimination on Reference Associations (#2041) * Update SqlTreeNodeBean#appendFromBaseTable to add discriminator values to the join * Update tests to reflect new generated SQL --- .../server/query/SqlTreeNodeBean.java | 9 ++++++ .../inheritance/TestInheritanceJoins.java | 28 ++++++++++++++++--- .../bothsides/TestInheritanceBothSides.java | 4 +-- .../inheritance/model/Configurations.java | 19 +++++++++++-- .../TestMediaInheritanceJoinToMany.java | 2 +- 5 files changed, 52 insertions(+), 10 deletions(-) diff --git a/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java b/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java index 956023edb..e0c87512f 100644 --- a/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java +++ b/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java @@ -667,6 +667,9 @@ class SqlTreeNodeBean implements SqlTreeNode { */ SqlJoinType appendFromBaseTable(DbSqlContext ctx, SqlJoinType joinType) { SqlJoinType sqlJoinType = appendFromAsJoin(ctx, joinType); + if (inheritInfo != null) { + appendJoinDiscriminator(ctx); + } if (desc.isSoftDelete() && temporalMode != SpiQuery.TemporalMode.SOFT_DELETED) { ctx.append("and ").append(desc.getSoftDeletePredicate(ctx.getTableAlias(prefix))).append(" "); } @@ -695,6 +698,12 @@ class SqlTreeNodeBean implements SqlTreeNode { return nodeBeanProp.addJoin(joinType, prefix, ctx); } + void appendJoinDiscriminator(DbSqlContext ctx) { + if (inheritInfo.getWhere() == null) return; + String alias = ctx.getTableAlias(prefix); + ctx.append(" and ").append(alias).append(".").append(inheritInfo.getWhere()); + } + /** * Summary description. */ diff --git a/src/test/java/org/tests/inheritance/TestInheritanceJoins.java b/src/test/java/org/tests/inheritance/TestInheritanceJoins.java index 445005cae..e43e89935 100644 --- a/src/test/java/org/tests/inheritance/TestInheritanceJoins.java +++ b/src/test/java/org/tests/inheritance/TestInheritanceJoins.java @@ -1,8 +1,6 @@ package org.tests.inheritance; -import io.ebean.BaseTestCase; -import io.ebean.Ebean; -import io.ebean.EbeanServer; +import io.ebean.*; import org.tests.inheritance.model.CalculationResult; import org.tests.inheritance.model.Configurations; import org.tests.inheritance.model.GroupConfiguration; @@ -10,6 +8,7 @@ import org.tests.inheritance.model.ProductConfiguration; import org.junit.Assert; import org.junit.Test; +import java.util.Collections; import java.util.List; public class TestInheritanceJoins extends BaseTestCase { @@ -86,7 +85,7 @@ public class TestInheritanceJoins extends BaseTestCase { final GroupConfiguration gc = new GroupConfiguration("GC1"); - configurations.add(gc); + configurations.addGroupConfiguration(gc); server.save(gc); @@ -112,4 +111,25 @@ public class TestInheritanceJoins extends BaseTestCase { Assert.assertNotNull(configurationsQueried); } + @Test + public void testMultipleAssocManyWithSameInheritanceBase() { + Database database = DB.getDefault(); + + Configurations configurations = new Configurations(); + database.save(configurations); + + GroupConfiguration gc = new GroupConfiguration(); + gc.setConfigurations(configurations); + database.save(gc); + + ProductConfiguration pc = new ProductConfiguration(); + pc.setConfigurations(configurations); + database.save(pc); + + Configurations configurationsQueried = database.find(Configurations.class).fetch("groupConfigurations").fetch("productConfigurations").where().idEq(configurations.getId()).findOne(); + + Assert.assertEquals(Collections.singletonList(gc), configurationsQueried.getGroupConfigurations()); + Assert.assertEquals(Collections.singletonList(pc), configurationsQueried.getProductConfigurations()); + } + } diff --git a/src/test/java/org/tests/inheritance/bothsides/TestInheritanceBothSides.java b/src/test/java/org/tests/inheritance/bothsides/TestInheritanceBothSides.java index e6d1dc44a..8de3776aa 100644 --- a/src/test/java/org/tests/inheritance/bothsides/TestInheritanceBothSides.java +++ b/src/test/java/org/tests/inheritance/bothsides/TestInheritanceBothSides.java @@ -39,7 +39,7 @@ public class TestInheritanceBothSides extends BaseTestCase { final Query query = DB.find(SourceA.class).fetch("target", "name").order("pos"); query.findList(); - assertThat(sqlOf(query)).contains("select t0.dtype, t0.id, t0.name, t0.pos, t1.dtype, t1.id, t1.name from source_base t0 left join target_base t1 on t1.id = t0.target_id where t0.dtype = 'SourceA' order by t0.pos"); + assertThat(sqlOf(query)).contains("select t0.dtype, t0.id, t0.name, t0.pos, t1.dtype, t1.id, t1.name from source_base t0 left join target_base t1 on t1.id = t0.target_id and t1.dtype = 'Target1' where t0.dtype = 'SourceA' order by t0.pos"); } @Test @@ -89,7 +89,7 @@ public class TestInheritanceBothSides extends BaseTestCase { final List sql = LoggedSqlCollector.stop(); assertThat(sql).hasSize(1); - assertSql(sql.get(0)).contains("select t0.dtype, t0.id, t0.name, t0.pos, t1.dtype, t1.id, t1.name from source_base t0 left join target_base t1 on t1.id = t0.target_id where t0.dtype = 'SourceA' order by t0.pos"); + assertSql(sql.get(0)).contains("select t0.dtype, t0.id, t0.name, t0.pos, t1.dtype, t1.id, t1.name from source_base t0 left join target_base t1 on t1.id = t0.target_id and t1.dtype = 'Target1' where t0.dtype = 'SourceA' order by t0.pos"); } /** diff --git a/src/test/java/org/tests/inheritance/model/Configurations.java b/src/test/java/org/tests/inheritance/model/Configurations.java index e8b4c194c..7afed20a6 100644 --- a/src/test/java/org/tests/inheritance/model/Configurations.java +++ b/src/test/java/org/tests/inheritance/model/Configurations.java @@ -17,12 +17,13 @@ public class Configurations { @OneToMany private List groupConfigurations; + @OneToMany + private List productConfigurations; public Integer getId() { return id; } - public void setId(Integer id) { this.id = id; } @@ -39,13 +40,25 @@ public class Configurations { return groupConfigurations; } - public void setGroupConfigurations(List groupConfigurations) { this.groupConfigurations = groupConfigurations; } - public void add(GroupConfiguration groupConfiguration) { + public void addGroupConfiguration(GroupConfiguration groupConfiguration) { groupConfiguration.setConfigurations(this); groupConfigurations.add(groupConfiguration); } + + public List getProductConfigurations() { + return productConfigurations; + } + + public void setProductConfigurations(List productConfigurations) { + this.productConfigurations = productConfigurations; + } + + public void addProductConfiguration(ProductConfiguration productConfiguration) { + productConfiguration.setConfigurations(this); + productConfigurations.add(productConfiguration); + } } diff --git a/src/test/java/org/tests/model/inheritmany/TestMediaInheritanceJoinToMany.java b/src/test/java/org/tests/model/inheritmany/TestMediaInheritanceJoinToMany.java index 16c00ea07..f4ff423ea 100644 --- a/src/test/java/org/tests/model/inheritmany/TestMediaInheritanceJoinToMany.java +++ b/src/test/java/org/tests/model/inheritmany/TestMediaInheritanceJoinToMany.java @@ -29,7 +29,7 @@ public class TestMediaInheritanceJoinToMany extends BaseTestCase { Assert.assertNotNull(profile); String generatedSql = query.getGeneratedSql(); - assertSql(generatedSql).contains("select t0.id, t0.name, t1.type, t1.id, t1.url, t1.note from mprofile t0 left join mmedia t1 on t1.id = t0.picture_id where t0.name = ?"); + assertSql(generatedSql).contains("select t0.id, t0.name, t1.type, t1.id, t1.url, t1.note from mprofile t0 left join mmedia t1 on t1.id = t0.picture_id and t1.type = 'Picture' where t0.name = ?"); assertSql(generatedSql).contains("where t0.name = ?"); }