This is an automated email from the ASF dual-hosted git repository. ntimofeev pushed a commit to branch STABLE-4.2 in repository https://gitbox.apache.org/repos/asf/cayenne.git
The following commit(s) were added to refs/heads/STABLE-4.2 by this push: new 079fbe7ba CAY-2871 QualifierTranslator breaks on a relationship with a compound FK 079fbe7ba is described below commit 079fbe7ba239166af8cab02ac34c3a5feb42124b Author: Nikita Timofeev <stari...@gmail.com> AuthorDate: Tue Sep 3 18:33:20 2024 +0400 CAY-2871 QualifierTranslator breaks on a relationship with a compound FK --- RELEASE-NOTES.txt | 2 +- .../translator/select/QualifierTranslator.java | 4 ++- .../translator/select/QualifierTranslatorIT.java | 29 +++++++++++++++++++++- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index f7af42b81..8ab4fb259 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -19,7 +19,7 @@ Bug Fixes: CAY-2866 DefaultDataDomainFlushAction breaks on circular relationship update CAY-2868 Regression: DefaultDbRowOpSorter shouldn't sort update operations - +CAY-2871 QualifierTranslator breaks on a relationship with a compound FK ---------------------------------- Release: 4.2.1 diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java index 765b14969..8147f31fa 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java @@ -64,7 +64,9 @@ class QualifierTranslator implements TraversalHandler { QualifierTranslator(TranslatorContext context) { this.context = context; this.pathTranslator = context.getPathTranslator(); - this.expressionsToSkip = new HashSet<>(); + // must use identity comparison for the node skipping, or it could skip the wrong node + // and mess everything up, see for example CAY-2871 + this.expressionsToSkip = Collections.newSetFromMap(new IdentityHashMap<>()); this.nodeStack = new ArrayDeque<>(); } diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorIT.java index 7cdd4b2a9..15f1bd32a 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorIT.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorIT.java @@ -30,13 +30,14 @@ import org.apache.cayenne.test.jdbc.DBHelper; import org.apache.cayenne.test.jdbc.TableHelper; import org.apache.cayenne.testdo.compound.CompoundFkTestEntity; import org.apache.cayenne.testdo.compound.CompoundPkTestEntity; -import org.apache.cayenne.unit.UnitDbAdapter; import org.apache.cayenne.unit.di.server.CayenneProjects; import org.apache.cayenne.unit.di.server.ServerCase; import org.apache.cayenne.unit.di.server.UseServerRuntime; import org.junit.Before; import org.junit.Test; +import java.util.List; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -57,6 +58,7 @@ public class QualifierTranslatorIT extends ServerCase { TableHelper tCompoundPKTest = new TableHelper(dbHelper, "COMPOUND_PK_TEST"); tCompoundPKTest.setColumns("KEY1", "KEY2", "NAME"); tCompoundPKTest.insert("PK1", "PK2", "BBB"); + tCompoundPKTest.insert("PK3", "PK4", "CCC"); } @Test @@ -82,4 +84,29 @@ public class QualifierTranslatorIT extends ServerCase { assertEquals(" ( ( ( t0.F_KEY1 = 'PK1' ) AND ( t0.F_KEY2 = 'PK2' ) ) AND t0.NAME LIKE 'test%' ) AND t0.NAME LIKE '%a%'", visitor.getSQLString()); } + @Test + public void testMultipleCompoundPK() { + List<CompoundPkTestEntity> testEntity = ObjectSelect.query(CompoundPkTestEntity.class) + .limit(2) + .select(context); + assertNotNull(testEntity); + assertEquals(2, testEntity.size()); + + ObjectSelect<CompoundFkTestEntity> query = ObjectSelect.query(CompoundFkTestEntity.class) + .where(CompoundFkTestEntity.TO_COMPOUND_PK.eq(testEntity.get(0))) + .or(CompoundFkTestEntity.TO_COMPOUND_PK.eq(testEntity.get(1))); + + DefaultSelectTranslator translator + = new DefaultSelectTranslator(query, runtime.getDataDomain().getDefaultNode().getAdapter(), context.getEntityResolver()); + + QualifierTranslator qualifierTranslator = translator.getContext().getQualifierTranslator(); + + Node node = qualifierTranslator.translate(query.getWhere()); + + SQLGenerationVisitor visitor = new SQLGenerationVisitor(new StringBuilderAppendable()); + node.visit(visitor); + + assertEquals(" ( ( t0.F_KEY1 = 'PK1' ) AND ( t0.F_KEY2 = 'PK2' ) ) OR ( ( t0.F_KEY1 = 'PK3' ) AND ( t0.F_KEY2 = 'PK4' ) )", visitor.getSQLString()); + } + }