From 08f240cd606eb59760979defbdd142265ecdca5c Mon Sep 17 00:00:00 2001 From: Will Dazey Date: Mon, 24 May 2021 19:42:58 -0500 Subject: [PATCH] Bug 573361: Add support for parameters within CriteriaBuilder case/coalesce expressions Signed-off-by: Will Dazey --- .../jpa/test/query/TestQueryCase.java | 771 +++++++++++++++++- .../jpa/test/query/TestQueryCoalesce.java | 224 +++++ .../jpa/querydef/CriteriaBuilderImpl.java | 103 ++- 3 files changed, 1041 insertions(+), 57 deletions(-) create mode 100644 jpa/eclipselink.jpa.test.jse/src/org/eclipse/persistence/jpa/test/query/TestQueryCoalesce.java diff --git a/jpa/eclipselink.jpa.test.jse/src/org/eclipse/persistence/jpa/test/query/TestQueryCase.java b/jpa/eclipselink.jpa.test.jse/src/org/eclipse/persistence/jpa/test/query/TestQueryCase.java index 04dd9beab82..6d9fdea94c3 100644 --- a/jpa/eclipselink.jpa.test.jse/src/org/eclipse/persistence/jpa/test/query/TestQueryCase.java +++ b/jpa/eclipselink.jpa.test.jse/src/org/eclipse/persistence/jpa/test/query/TestQueryCase.java @@ -25,6 +25,7 @@ import javax.persistence.criteria.CriteriaBuilder.SimpleCase; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Expression; +import javax.persistence.criteria.ParameterExpression; import javax.persistence.criteria.Root; import org.eclipse.persistence.jpa.test.framework.DDLGen; @@ -34,19 +35,20 @@ import org.eclipse.persistence.jpa.test.query.model.Dto01; import org.eclipse.persistence.jpa.test.query.model.EntityTbl01; import org.eclipse.persistence.jpa.test.query.model.EntityTbl01_; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(EmfRunner.class) public class TestQueryCase { @Emf(createTables = DDLGen.DROP_CREATE, classes = { EntityTbl01.class }, - properties = { @Property(name="eclipselink.logging.level", value="FINE")}) + properties = { @Property(name="eclipselink.logging.level", value="FINE") }) private EntityManagerFactory emf; private static boolean POPULATED = false; @Test - public void testQueryCase1() { + public void testQuery_JPQL_Case_Literals_1() { if (emf == null) return; @@ -54,8 +56,8 @@ public void testQueryCase1() { populate(); EntityManager em = emf.createEntityManager(); - try { + // test 1 TypedQuery query = em.createQuery("" + "SELECT t FROM EntityTbl01 t " + "WHERE t.itemString1 = ( " @@ -69,6 +71,7 @@ public void testQueryCase1() { assertNotNull(dto01); assertEquals(0, dto01.size()); + // test 2 query = em.createQuery("" + "SELECT t FROM EntityTbl01 t " + "WHERE t.itemString1 = ( " @@ -86,8 +89,27 @@ public void testQueryCase1() { assertEquals("C", dto01.get(0).getItemString3()); assertEquals("D", dto01.get(0).getItemString4()); assertEquals(new Integer(1), dto01.get(0).getItemInteger1()); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } + + @Test + public void testQuery_Criteria_Case_Literals_1() { + if (emf == null) + return; - // test 1 equivalent CriteriaBuilder + if(!POPULATED) + populate(); + + EntityManager em = emf.createEntityManager(); + try { + // test 1 CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cquery = cb.createQuery(EntityTbl01.class); Root root = cquery.from(EntityTbl01.class); @@ -99,12 +121,12 @@ public void testQueryCase1() { .otherwise("033020"); cquery.where(cb.equal(root.get(EntityTbl01_.itemString1), selectCase)); - query = em.createQuery(cquery); - dto01 = query.getResultList(); + TypedQuery query = em.createQuery(cquery); + List dto01 = query.getResultList(); assertNotNull(dto01); assertEquals(0, dto01.size()); - // test 2 equivalent CriteriaBuilder + // test 2 cb = em.getCriteriaBuilder(); cquery = cb.createQuery(EntityTbl01.class); root = cquery.from(EntityTbl01.class); @@ -137,7 +159,163 @@ public void testQueryCase1() { } @Test - public void testQueryCase2() { + public void testQuery_JPQL_Case_Parameters_1() { + if (emf == null) + return; + + if(!POPULATED) + populate(); + + EntityManager em = emf.createEntityManager(); + + try { + // test 1 + TypedQuery query = em.createQuery("" + + "SELECT t FROM EntityTbl01 t " + + "WHERE t.itemString1 = ( " + + "CASE t.itemInteger1 " + + "WHEN ?1 THEN ?2 " + + "WHEN ?3 THEN ?4 " + + "ELSE ?5 " + + "END )", EntityTbl01.class); + query.setParameter(1, 1000); + query.setParameter(2, "047010"); + query.setParameter(3, 100); + query.setParameter(4, "023010"); + query.setParameter(5, "033020"); + + List dto01 = query.getResultList(); + assertNotNull(dto01); + assertEquals(0, dto01.size()); + + // test 2 + query = em.createQuery("" + + "SELECT t FROM EntityTbl01 t " + + "WHERE t.itemString1 = ( " + + "CASE t.itemInteger1 " + + "WHEN ?1 THEN ?2 " + + "WHEN ?3 THEN ?4 " + + "ELSE ?5 " + + "END )", EntityTbl01.class); + query.setParameter(1, 1); + query.setParameter(2, "A"); + query.setParameter(3, 100); + query.setParameter(4, "B"); + query.setParameter(5, "C"); + + dto01 = query.getResultList(); + assertNotNull(dto01); + assertEquals(1, dto01.size()); + + assertEquals("A", dto01.get(0).getItemString1()); + assertEquals("B", dto01.get(0).getItemString2()); + assertEquals("C", dto01.get(0).getItemString3()); + assertEquals("D", dto01.get(0).getItemString4()); + assertEquals(new Integer(1), dto01.get(0).getItemInteger1()); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } + + @Test + // Test disabled because it makes use of currently unsupported CriteriaBuilder API calls. + @Ignore + public void testQuery_Criteria_Case_Parameters_1() { + if (emf == null) + return; + + if(!POPULATED) + populate(); + + EntityManager em = emf.createEntityManager(); + + try { + // test 1 + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cquery = cb.createQuery(EntityTbl01.class); + Root root = cquery.from(EntityTbl01.class); + cquery.multiselect(root); + + ParameterExpression checkParam1 = cb.parameter(Integer.class); + ParameterExpression checkParam2 = cb.parameter(Integer.class); + ParameterExpression resultParam1 = cb.parameter(String.class); + ParameterExpression resultParam2 = cb.parameter(String.class); + ParameterExpression resultParam3 = cb.parameter(String.class); + + // Currently unsupported by the JPA API + // https://github.com/eclipse-ee4j/jpa-api/issues/315 +// Expression selectCase = cb.selectCase(root.get(EntityTbl01_.itemInteger1)) +// .when(checkParam1, resultParam1) +// .when(checkParam2, resultParam2) +// .otherwise(resultParam3); +// Predicate pred = cb.equal(root.get(EntityTbl01_.itemString1), selectCase); +// cquery.where(pred); + + TypedQuery query = em.createQuery(cquery); + query.setParameter(checkParam1, 1000); + query.setParameter(resultParam1, "047010"); + query.setParameter(checkParam2, 100); + query.setParameter(resultParam2, "023010"); + query.setParameter(resultParam3, "033020"); + + List dto01 = query.getResultList(); + assertNotNull(dto01); + assertEquals(0, dto01.size()); + + // test 2 + cb = em.getCriteriaBuilder(); + cquery = cb.createQuery(EntityTbl01.class); + root = cquery.from(EntityTbl01.class); + cquery.multiselect(root); + + checkParam1 = cb.parameter(Integer.class); + checkParam2 = cb.parameter(Integer.class); + resultParam1 = cb.parameter(String.class); + resultParam2 = cb.parameter(String.class); + resultParam3 = cb.parameter(String.class); + + // Currently unsupported by the JPA API + // https://github.com/eclipse-ee4j/jpa-api/issues/315 +// selectCase = cb.selectCase(root.get(EntityTbl01_.itemInteger1)) +// .when(checkParam1, resultParam1) +// .when(checkParam2, resultParam2) +// .otherwise(resultParam3); +// pred = cb.equal(root.get(EntityTbl01_.itemString1), selectCase); +// cquery.where(pred); + + query = em.createQuery(cquery); + query.setParameter(checkParam1, 1); + query.setParameter(resultParam1, "A"); + query.setParameter(checkParam2, 100); + query.setParameter(resultParam2, "B"); + query.setParameter(resultParam3, "C"); + + dto01 = query.getResultList(); + assertNotNull(dto01); + assertEquals(1, dto01.size()); + + assertEquals("A", dto01.get(0).getItemString1()); + assertEquals("B", dto01.get(0).getItemString2()); + assertEquals("C", dto01.get(0).getItemString3()); + assertEquals("D", dto01.get(0).getItemString4()); + assertEquals(new Integer(1), dto01.get(0).getItemInteger1()); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } + + @Test + public void testQuery_JPQL_Case_Literals_2() { if (emf == null) return; @@ -146,6 +324,7 @@ public void testQueryCase2() { EntityManager em = emf.createEntityManager(); try { + // test 1 TypedQuery query = em.createQuery("" + "SELECT t FROM EntityTbl01 t " + "WHERE t.itemString1 = ( " @@ -159,6 +338,7 @@ public void testQueryCase2() { assertNotNull(dto01); assertEquals(0, dto01.size()); + // test 2 query = em.createQuery("" + "SELECT t FROM EntityTbl01 t " + "WHERE t.itemString1 = ( " @@ -177,17 +357,27 @@ public void testQueryCase2() { assertEquals("C", dto01.get(0).getItemString3()); assertEquals("D", dto01.get(0).getItemString4()); assertEquals(new Integer(1), dto01.get(0).getItemInteger1()); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } - query = em.createQuery("" - + "SELECT t FROM EntityTbl01 t " - + "WHERE t.itemString1 = ( " - + "CASE " - + "WHEN t.itemInteger1 = 1 AND t.KeyString = 'Key01' THEN 'A' " - + "WHEN t.itemInteger1 = 100 THEN 'B' " - + "ELSE 'C' " - + "END )", EntityTbl01.class); + @Test + public void testQuery_Criteria_Case_Literals_2() { + if (emf == null) + return; + + if(!POPULATED) + populate(); - // test 1 equivalent CriteriaBuilder + EntityManager em = emf.createEntityManager(); + try { + // test 1 CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cquery = cb.createQuery(EntityTbl01.class); Root root = cquery.from(EntityTbl01.class); @@ -199,12 +389,12 @@ public void testQueryCase2() { .otherwise("033020"); cquery.where(cb.equal(root.get(EntityTbl01_.itemString1), selectCase)); - query = em.createQuery(cquery); - dto01 = query.getResultList(); + TypedQuery query = em.createQuery(cquery); + List dto01 = query.getResultList(); assertNotNull(dto01); assertEquals(0, dto01.size()); - // test 2 equivalent CriteriaBuilder + // test 2 cb = em.getCriteriaBuilder(); cquery = cb.createQuery(EntityTbl01.class); root = cquery.from(EntityTbl01.class); @@ -239,7 +429,151 @@ public void testQueryCase2() { } @Test - public void testQueryCase3() { + public void testQuery_JPQL_Case_Parameters_2() { + if (emf == null) + return; + + if(!POPULATED) + populate(); + + EntityManager em = emf.createEntityManager(); + try { + // test 1 + TypedQuery query = em.createQuery("" + + "SELECT t FROM EntityTbl01 t " + + "WHERE t.itemString1 = ( " + + "CASE " + + "WHEN t.itemInteger1 = ?1 THEN ?2 " + + "WHEN t.itemInteger1 = ?3 THEN ?4 " + + "ELSE ?5 " + + "END )", EntityTbl01.class); + query.setParameter(1, 1000); + query.setParameter(2, "047010"); + query.setParameter(3, 100); + query.setParameter(4, "023010"); + query.setParameter(5, "033020"); + + List dto01 = query.getResultList(); + assertNotNull(dto01); + assertEquals(0, dto01.size()); + + // test 2 + query = em.createQuery("" + + "SELECT t FROM EntityTbl01 t " + + "WHERE t.itemString1 = ( " + + "CASE " + + "WHEN t.itemInteger1 = ?1 THEN ?2 " + + "WHEN t.itemInteger1 = ?3 THEN ?4 " + + "ELSE ?5 " + + "END )", EntityTbl01.class); + query.setParameter(1, 1); + query.setParameter(2, "A"); + query.setParameter(3, 100); + query.setParameter(4, "B"); + query.setParameter(5, "C"); + + dto01 = query.getResultList(); + assertNotNull(dto01); + assertEquals(1, dto01.size()); + + assertEquals("A", dto01.get(0).getItemString1()); + assertEquals("B", dto01.get(0).getItemString2()); + assertEquals("C", dto01.get(0).getItemString3()); + assertEquals("D", dto01.get(0).getItemString4()); + assertEquals(new Integer(1), dto01.get(0).getItemInteger1()); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } + + @Test + public void testQuery_Criteria_Case_Parameters_2() { + if (emf == null) + return; + + if(!POPULATED) + populate(); + + EntityManager em = emf.createEntityManager(); + try { + // test 1 + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cquery = cb.createQuery(EntityTbl01.class); + Root root = cquery.from(EntityTbl01.class); + cquery.select(root); + + ParameterExpression checkParam1 = cb.parameter(Integer.class); + ParameterExpression checkParam2 = cb.parameter(Integer.class); + ParameterExpression resultParam1 = cb.parameter(String.class); + ParameterExpression resultParam2 = cb.parameter(String.class); + ParameterExpression resultParam3 = cb.parameter(String.class); + + Expression selectCase = cb.selectCase() + .when(cb.equal(root.get(EntityTbl01_.itemInteger1), checkParam1), resultParam1) + .when(cb.equal(root.get(EntityTbl01_.itemInteger1), checkParam2), resultParam2) + .otherwise(resultParam3); + cquery.where(cb.equal(root.get(EntityTbl01_.itemString1), selectCase)); + + TypedQuery query = em.createQuery(cquery); + query.setParameter(checkParam1, 1000); + query.setParameter(resultParam1, "047010"); + query.setParameter(checkParam2, 100); + query.setParameter(resultParam2, "023010"); + query.setParameter(resultParam3, "033020"); + List dto01 = query.getResultList(); + assertNotNull(dto01); + assertEquals(0, dto01.size()); + + // test 2 + cb = em.getCriteriaBuilder(); + cquery = cb.createQuery(EntityTbl01.class); + root = cquery.from(EntityTbl01.class); + cquery.select(root); + + checkParam1 = cb.parameter(Integer.class); + checkParam2 = cb.parameter(Integer.class); + resultParam1 = cb.parameter(String.class); + resultParam2 = cb.parameter(String.class); + resultParam3 = cb.parameter(String.class); + + selectCase = cb.selectCase() + .when(cb.equal(root.get(EntityTbl01_.itemInteger1), checkParam1), resultParam1) + .when(cb.equal(root.get(EntityTbl01_.itemInteger1), checkParam2), resultParam2) + .otherwise(resultParam3); + cquery.where(cb.equal(root.get(EntityTbl01_.itemString1), selectCase)); + + query = em.createQuery(cquery); + query.setParameter(checkParam1, 1); + query.setParameter(resultParam1, "A"); + query.setParameter(checkParam2, 100); + query.setParameter(resultParam2, "B"); + query.setParameter(resultParam3, "C"); + dto01 = query.getResultList(); + assertNotNull(dto01); + assertEquals(1, dto01.size()); + + assertEquals("A", dto01.get(0).getItemString1()); + assertEquals("B", dto01.get(0).getItemString2()); + assertEquals("C", dto01.get(0).getItemString3()); + assertEquals("D", dto01.get(0).getItemString4()); + assertEquals(new Integer(1), dto01.get(0).getItemInteger1()); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } + + @Test + public void testQuery_JPQL_Case_Literals_3() { if (emf == null) return; @@ -282,14 +616,35 @@ public void testQueryCase3() { assertNull(dto01.get(0).getStr4()); assertEquals(new Integer(2), dto01.get(0).getInteger1()); assertEquals(new Integer(2), dto01.get(0).getInteger2()); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } + @Test + // This test is disabled because it fails with a Constructor type issue + @Ignore + public void testQuery_Criteria_Case_Literals_3() { + if (emf == null) + return; + + if(!POPULATED) + populate(); + + EntityManager em = emf.createEntityManager(); + try { // test equivalent CriteriaBuilder CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cquery = cb.createQuery(Dto01.class); Root root = cquery.from(EntityTbl01.class); SimpleCase selectCase = cb.selectCase(root.get(EntityTbl01_.itemString2)); - selectCase.when("J", "Japan") + selectCase.when("J", "Japan") .otherwise("Other"); Expression selectCase2 = cb.selectCase() @@ -308,9 +663,74 @@ public void testQueryCase3() { cquery.groupBy(root.get(EntityTbl01_.itemString1), root.get(EntityTbl01_.itemString2)); - query = em.createQuery(cquery); + TypedQuery query = em.createQuery(cquery); - dto01 = query.getResultList(); + List dto01 = query.getResultList(); + assertNotNull(dto01); + assertEquals(1, dto01.size()); + assertEquals("A", dto01.get(0).getStr1()); + assertEquals("Other", dto01.get(0).getStr2()); + assertNull(dto01.get(0).getStr3()); + assertNull(dto01.get(0).getStr4()); + assertEquals(new Integer(2), dto01.get(0).getInteger1()); + assertEquals(new Integer(2), dto01.get(0).getInteger2()); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } + + @Test + // This test is disabled because it fails with a Constructor type issue + @Ignore + public void testQuery_JPQL_Case_Parameters_3() { + if (emf == null) + return; + + if(!POPULATED) + populate(); + + EntityManager em = emf.createEntityManager(); + try { + TypedQuery query = em.createQuery("" + + "SELECT new org.eclipse.persistence.jpa.test.query.model.Dto01(" + + "t.itemString1, " // String + + "CASE t.itemString2 " // String + + "WHEN ?1 THEN ?2 " + + "ELSE ?3 " + + "END " + + ", " + + "SUM(" // Returns Long (4.8.5) + + "CASE " + + "WHEN t.itemString3 = ?4 " + + "THEN ?5 ELSE ?6 " + + "END" + +") " + + ", " + + "SUM(" // Returns Long (4.8.5) + + "CASE " + + "WHEN t.itemString4 = ?7 " + + "THEN ?8 ELSE ?9 " + + "END" + + ") " + + ") " + + "FROM EntityTbl01 t " + + "GROUP BY t.itemString1, t.itemString2", Dto01.class); + query.setParameter(1, "J"); + query.setParameter(2, "Japan"); + query.setParameter(3, "Other"); + query.setParameter(4, "C"); + query.setParameter(5, 1); + query.setParameter(6, 0); + query.setParameter(7, "D"); + query.setParameter(8, 1); + query.setParameter(9, 0); + + List dto01 = query.getResultList(); assertNotNull(dto01); assertEquals(1, dto01.size()); assertEquals("A", dto01.get(0).getStr1()); @@ -330,7 +750,82 @@ public void testQueryCase3() { } @Test - public void testQueryCase4() { + // This test is disabled because it fails with a Constructor type issue + @Ignore + public void testQuery_Criteria_Case_Parameters_3() { + if (emf == null) + return; + + if(!POPULATED) + populate(); + + EntityManager em = emf.createEntityManager(); + try { + // test equivalent CriteriaBuilder + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cquery = cb.createQuery(Dto01.class); + Root root = cquery.from(EntityTbl01.class); + + ParameterExpression checkParam1 = cb.parameter(String.class); + ParameterExpression checkParam2 = cb.parameter(String.class); + ParameterExpression checkParam3 = cb.parameter(String.class); + ParameterExpression resultParam1 = cb.parameter(String.class); + ParameterExpression resultParam2 = cb.parameter(String.class); + ParameterExpression resultParam3 = cb.parameter(Long.class); + ParameterExpression resultParam4 = cb.parameter(Long.class); + + // Currently unsupported by the JPA API + // https://github.com/eclipse-ee4j/jpa-api/issues/315 +// SimpleCase selectCase = cb.selectCase(root.get(EntityTbl01_.itemString2)); +// selectCase.when(checkParam1, resultParam1) +// .otherwise(resultParam2); + + Expression selectCase2 = cb.selectCase() + .when(cb.equal(root.get(EntityTbl01_.itemString3), checkParam2), resultParam3) + .otherwise(resultParam4); + + Expression selectCase3 = cb.selectCase() + .when(cb.equal(root.get(EntityTbl01_.itemString4), checkParam3), resultParam3) + .otherwise(resultParam4); + + cquery.select(cb.construct(Dto01.class, + root.get(EntityTbl01_.itemString1), +// selectCase, + cb.sum(selectCase2), + cb.sum(selectCase3))); + + cquery.groupBy(root.get(EntityTbl01_.itemString1), root.get(EntityTbl01_.itemString2)); + + TypedQuery query = em.createQuery(cquery); + query.setParameter(checkParam1, "J"); + query.setParameter(resultParam1, "Japan"); + query.setParameter(resultParam2, "Other"); + query.setParameter(checkParam2, "C"); + query.setParameter(checkParam3, "D"); + query.setParameter(resultParam3, new Long(1)); + query.setParameter(resultParam4, new Long(1)); + List dto01 = query.getResultList(); + + assertNotNull(dto01); + assertEquals(1, dto01.size()); + assertEquals("A", dto01.get(0).getStr1()); + assertEquals("Other", dto01.get(0).getStr2()); + assertNull(dto01.get(0).getStr3()); + assertNull(dto01.get(0).getStr4()); + assertEquals(new Integer(2), dto01.get(0).getInteger1()); + assertEquals(new Integer(2), dto01.get(0).getInteger2()); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } + + @Test + public void testQuery_JPQL_Case_Literals_4() { if (emf == null) return; @@ -354,7 +849,26 @@ public void testQueryCase4() { assertEquals(2, intList.size()); assertEquals(new Integer(100), intList.get(0)); assertEquals(new Integer(100), intList.get(1)); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } + + @Test + public void testQuery_Criteria_Case_Literals_4() { + if (emf == null) + return; + + if(!POPULATED) + populate(); + EntityManager em = emf.createEntityManager(); + try { // test equivalent CriteriaBuilder CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cquery = cb.createQuery(Integer.class); @@ -367,9 +881,9 @@ public void testQueryCase4() { cquery.select(selectCase); - query = em.createQuery(cquery); + TypedQuery query = em.createQuery(cquery); - intList = query.getResultList(); + List intList = query.getResultList(); assertNotNull(intList); assertEquals(2, intList.size()); assertEquals(new Integer(100), intList.get(0)); @@ -385,7 +899,100 @@ public void testQueryCase4() { } @Test - public void testQueryCase5() { + public void testQuery_JPQL_Case_Parameters_4() { + if (emf == null) + return; + + if(!POPULATED) + populate(); + + EntityManager em = emf.createEntityManager(); + try { + TypedQuery query = em.createQuery("" + + "SELECT (" + + "CASE t.itemString2 " + + "WHEN ?1 THEN ?2 " + + "WHEN ?3 THEN ?4 " + + "ELSE ?5 " + + "END " + + ") " + + "FROM EntityTbl01 t", Number.class); + query.setParameter(1, "A"); + query.setParameter(2, 42); + query.setParameter(3, "B"); + query.setParameter(4, 100); + query.setParameter(5, 0); + + List intList = query.getResultList(); + assertNotNull(intList); + assertEquals(2, intList.size()); + assertEquals(new Integer(100).intValue(), intList.get(0).intValue()); + assertEquals(new Integer(100).intValue(), intList.get(1).intValue()); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } + + @Test + // Test disabled because it makes use of currently unsupported CriteriaBuilder API calls. + @Ignore + public void testQuery_Criteria_Case_Parameters_4() { + if (emf == null) + return; + + if(!POPULATED) + populate(); + + EntityManager em = emf.createEntityManager(); + try { + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cquery = cb.createQuery(Number.class); + Root root = cquery.from(EntityTbl01.class); + + ParameterExpression checkParam1 = cb.parameter(String.class); + ParameterExpression checkParam2 = cb.parameter(String.class); + ParameterExpression resultParam1 = cb.parameter(Integer.class); + ParameterExpression resultParam2 = cb.parameter(Integer.class); + ParameterExpression resultParam3 = cb.parameter(Integer.class); + + // Currently unsupported by the JPA API + // https://github.com/eclipse-ee4j/jpa-api/issues/315 +// SimpleCase selectCase = cb.selectCase(root.get(EntityTbl01_.itemString2)); +// selectCase.when(checkParam1, resultParam1) +// .when(checkParam2, resultParam2) +// .otherwise(resultParam3); +// +// cquery.select(selectCase); + + TypedQuery query = em.createQuery(cquery); + query.setParameter(checkParam1, "A"); + query.setParameter(resultParam1, 42); + query.setParameter(checkParam2, "B"); + query.setParameter(resultParam2, 100); + query.setParameter(resultParam3, 0); + + List intList = query.getResultList(); + assertNotNull(intList); + assertEquals(2, intList.size()); + assertEquals(new Integer(100).intValue(), intList.get(0).intValue()); + assertEquals(new Integer(100).intValue(), intList.get(1).intValue()); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } + + @Test + public void testQuery_JPQL_Case_Literals_5() { if (emf == null) return; @@ -408,22 +1015,40 @@ public void testQueryCase5() { assertEquals(2, boolList.size()); assertEquals(true, boolList.get(0)); assertEquals(false, boolList.get(1)); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } - // test equivalent CriteriaBuilder + @Test + public void testQuery_Criteria_Case_Literals_5() { + if (emf == null) + return; + + if(!POPULATED) + populate(); + + EntityManager em = emf.createEntityManager(); + try { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cquery = cb.createQuery(Boolean.class); Root root = cquery.from(EntityTbl01.class); SimpleCase selectCase = cb.selectCase(root.get(EntityTbl01_.itemInteger1)); - selectCase.when(1, true) + selectCase.when(1, true) .otherwise(false); cquery.select(selectCase); cquery.orderBy(cb.asc(root.get(EntityTbl01_.itemInteger1))); - query = em.createQuery(cquery); + TypedQuery query = em.createQuery(cquery); - boolList = query.getResultList(); + List boolList = query.getResultList(); assertNotNull(boolList); assertEquals(2, boolList.size()); assertEquals(true, boolList.get(0)); @@ -438,6 +1063,88 @@ public void testQueryCase5() { } } + @Test + public void testQuery_JPQL_Case_Parameters_5() { + if (emf == null) + return; + + if(!POPULATED) + populate(); + + EntityManager em = emf.createEntityManager(); + try { + TypedQuery query = em.createQuery("" + + "SELECT (" + + "CASE " + + "WHEN t.itemInteger1 = ?1 THEN ?2 " + + "ELSE ?3 " + + "END " + + ") " + + "FROM EntityTbl01 t ORDER BY t.itemInteger1 ASC", Boolean.class); + query.setParameter(1, 1); + query.setParameter(2, true); + query.setParameter(3, false); + + List boolList = query.getResultList(); + assertNotNull(boolList); + assertEquals(2, boolList.size()); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } + + @Test + // Test disabled because it makes use of currently unsupported CriteriaBuilder API calls. + @Ignore + public void testQuery_Criteria_Case_Parameters_5() { + if (emf == null) + return; + + if(!POPULATED) + populate(); + + EntityManager em = emf.createEntityManager(); + try { + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cquery = cb.createQuery(Boolean.class); + Root root = cquery.from(EntityTbl01.class); + + ParameterExpression checkParam1 = cb.parameter(Integer.class); + ParameterExpression resultParam1 = cb.parameter(Boolean.class); + ParameterExpression resultParam2 = cb.parameter(Boolean.class); + + // Currently unsupported by the JPA API + // https://github.com/eclipse-ee4j/jpa-api/issues/315 +// SimpleCase selectCase = cb.selectCase(root.get(EntityTbl01_.itemInteger1)); +// selectCase.when(checkParam1, resultParam1) +// .otherwise(resultParam2); +// +// cquery.select(selectCase); + cquery.orderBy(cb.asc(root.get(EntityTbl01_.itemInteger1))); + + TypedQuery query = em.createQuery(cquery); + query.setParameter(checkParam1, 1); + query.setParameter(resultParam1, true); + query.setParameter(resultParam2, false); + + List boolList = query.getResultList(); + assertNotNull(boolList); + assertEquals(2, boolList.size()); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } + private void populate() { EntityManager em = emf.createEntityManager(); try { diff --git a/jpa/eclipselink.jpa.test.jse/src/org/eclipse/persistence/jpa/test/query/TestQueryCoalesce.java b/jpa/eclipselink.jpa.test.jse/src/org/eclipse/persistence/jpa/test/query/TestQueryCoalesce.java new file mode 100644 index 00000000000..63c9a079e94 --- /dev/null +++ b/jpa/eclipselink.jpa.test.jse/src/org/eclipse/persistence/jpa/test/query/TestQueryCoalesce.java @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2021 IBM Corporation. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, + * or the Eclipse Distribution License v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +// Contributors: +// IBM - Bug 573361: Add support for Parameters in CriteriaBuilder in Case/Coalesce expressions +package org.eclipse.persistence.jpa.test.query; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.List; +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Expression; +import javax.persistence.criteria.ParameterExpression; +import javax.persistence.criteria.Root; + +import org.eclipse.persistence.jpa.test.framework.DDLGen; +import org.eclipse.persistence.jpa.test.framework.Emf; +import org.eclipse.persistence.jpa.test.framework.EmfRunner; +import org.eclipse.persistence.jpa.test.framework.Property; +import org.eclipse.persistence.jpa.test.query.model.EntityTbl01; +import org.eclipse.persistence.jpa.test.query.model.EntityTbl01_; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(EmfRunner.class) +public class TestQueryCoalesce { + @Emf(createTables = DDLGen.DROP_CREATE, classes = { EntityTbl01.class }, + properties = { @Property(name="eclipselink.logging.level", value="FINE")}) + private EntityManagerFactory emf; + + private static boolean POPULATED = false; + + @Test + public void testQueryCoalesceLiterals1() { + if (emf == null) + return; + + if(!POPULATED) + populate(); + + EntityManager em = emf.createEntityManager(); + + try { + TypedQuery query = em.createQuery("" + + "SELECT t FROM EntityTbl01 t " + + "WHERE t.itemString2 = " + + "COALESCE (t.itemString1, 'Sample')", EntityTbl01.class); + + List dto01 = query.getResultList(); + assertNotNull(dto01); + assertEquals(0, dto01.size()); + + TypedQuery query2 = em.createQuery("" + + "SELECT COALESCE (t.itemString2, 'Sample') FROM EntityTbl01 t ORDER BY t.itemInteger1 ASC", String.class); + + List dto02 = query2.getResultList(); + assertNotNull(dto02); + assertEquals(2, dto02.size()); + + assertEquals("Sample", dto02.get(0)); + assertEquals("B", dto02.get(1)); + + // test 1 equivalent CriteriaBuilder + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cquery = cb.createQuery(EntityTbl01.class); + Root root = cquery.from(EntityTbl01.class); + cquery.select(root); + + Expression coalesce = cb.coalesce(root.get(EntityTbl01_.itemString1), "Sample"); + cquery.where(cb.equal(root.get(EntityTbl01_.itemString2), coalesce)); + + query = em.createQuery(cquery); + dto01 = query.getResultList(); + assertNotNull(dto01); + assertEquals(0, dto01.size()); + + // test 2 equivalent CriteriaBuilder + cb = em.getCriteriaBuilder(); + CriteriaQuery cquery2 = cb.createQuery(String.class); + root = cquery2.from(EntityTbl01.class); + Expression coalesce2 = cb.coalesce(root.get(EntityTbl01_.itemString2), "Sample"); + cquery2.multiselect(coalesce2); + + cquery2.orderBy(cb.asc(root.get(EntityTbl01_.itemInteger1))); + + query2 = em.createQuery(cquery2); + dto02 = query2.getResultList(); + assertNotNull(dto02); + assertEquals(2, dto02.size()); + + assertEquals("Sample", dto02.get(0)); + assertEquals("B", dto02.get(1)); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } + + @Test + public void testQueryCaseParameters1() { + if (emf == null) + return; + + if(!POPULATED) + populate(); + + EntityManager em = emf.createEntityManager(); + + try { + TypedQuery query = em.createQuery("" + + "SELECT t FROM EntityTbl01 t " + + "WHERE t.itemString2 = " + + "COALESCE (t.itemString1, ?1)", EntityTbl01.class); + query.setParameter(1, "Sample"); + + List dto01 = query.getResultList(); + assertNotNull(dto01); + assertEquals(0, dto01.size()); + + TypedQuery query2 = em.createQuery("" + + "SELECT COALESCE (t.itemString2, ?1) FROM EntityTbl01 t ORDER BY t.itemInteger1 ASC", String.class); + query2.setParameter(1, "Sample"); + + List dto02 = query2.getResultList(); + assertNotNull(dto02); + assertEquals(2, dto02.size()); + + assertEquals("Sample", dto02.get(0)); + assertEquals("B", dto02.get(1)); + + // test 1 equivalent CriteriaBuilder + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cquery = cb.createQuery(EntityTbl01.class); + Root root = cquery.from(EntityTbl01.class); + cquery.select(root); + + ParameterExpression checkParam1 = cb.parameter(String.class); + Expression coalesce = cb.coalesce(root.get(EntityTbl01_.itemString1), checkParam1); + cquery.where(cb.equal(root.get(EntityTbl01_.itemString2), coalesce)); + + query = em.createQuery(cquery); + query.setParameter(checkParam1, "Sample"); + dto01 = query.getResultList(); + assertNotNull(dto01); + assertEquals(0, dto01.size()); + + // test 2 equivalent CriteriaBuilder + cb = em.getCriteriaBuilder(); + CriteriaQuery cquery2 = cb.createQuery(String.class); + root = cquery2.from(EntityTbl01.class); + ParameterExpression checkParam2 = cb.parameter(String.class); + Expression coalesce2 = cb.coalesce(root.get(EntityTbl01_.itemString2), checkParam2); + cquery2.multiselect(coalesce2); + + cquery2.orderBy(cb.asc(root.get(EntityTbl01_.itemInteger1))); + + query2 = em.createQuery(cquery2); + query2.setParameter(checkParam2, "Sample"); + dto02 = query2.getResultList(); + assertNotNull(dto02); + assertEquals(2, dto02.size()); + + assertEquals("Sample", dto02.get(0)); + assertEquals("B", dto02.get(1)); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } + + private void populate() { + EntityManager em = emf.createEntityManager(); + try { + em.getTransaction().begin(); + + EntityTbl01 tbl1 = new EntityTbl01(); + tbl1.setKeyString("Key03"); + tbl1.setItemString1("A"); + tbl1.setItemString2(null); + tbl1.setItemString3("C"); + tbl1.setItemString4("D"); + tbl1.setItemInteger1(3); + em.persist(tbl1); + + EntityTbl01 tbl2 = new EntityTbl01(); + tbl2.setKeyString("Key04"); + tbl2.setItemString1("A"); + tbl2.setItemString2("B"); + tbl2.setItemString3("C"); + tbl2.setItemString4(null); + tbl2.setItemInteger1(4); + em.persist(tbl2); + + em.getTransaction().commit(); + + POPULATED = true; + } finally { + if(em.isOpen()) { + em.close(); + } + } + } +} \ No newline at end of file diff --git a/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/querydef/CriteriaBuilderImpl.java b/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/querydef/CriteriaBuilderImpl.java index 60c7c707aa2..8400dab0ce2 100644 --- a/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/querydef/CriteriaBuilderImpl.java +++ b/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/querydef/CriteriaBuilderImpl.java @@ -2241,10 +2241,14 @@ public In in(Expression expression){ * @return expression corresponding to the given coalesce expression */ @Override - public Expression coalesce(Expression x, Expression y){ + public Expression coalesce(Expression x, Expression y) { ArgumentListFunctionExpression coalesce = ((InternalSelection)x).getCurrentNode().coalesce(); - coalesce.addChild(((InternalSelection)x).getCurrentNode()); - coalesce.addChild(((InternalSelection)y).getCurrentNode()); + org.eclipse.persistence.expressions.Expression expX = ((InternalSelection)x).getCurrentNode(); + expX = org.eclipse.persistence.expressions.Expression.from(expX, coalesce); + coalesce.addChild(expX); + org.eclipse.persistence.expressions.Expression expY = ((InternalSelection)y).getCurrentNode(); + expY = org.eclipse.persistence.expressions.Expression.from(expY, coalesce); + coalesce.addChild(expY); return new CoalesceImpl(metamodel, x.getJavaType(), coalesce, buildList(x, y), "coalesce"); } @@ -2259,10 +2263,13 @@ public Expression coalesce(Expression x, Expression Expression coalesce(Expression x, Y y){ + public Expression coalesce(Expression x, Y y) { ArgumentListFunctionExpression coalesce = ((InternalSelection)x).getCurrentNode().coalesce(); - coalesce.addChild(((InternalSelection)x).getCurrentNode()); - coalesce.addChild(org.eclipse.persistence.expressions.Expression.from(y, new ExpressionBuilder())); + org.eclipse.persistence.expressions.Expression expX = ((InternalSelection)x).getCurrentNode(); + expX = org.eclipse.persistence.expressions.Expression.from(expX, coalesce); + coalesce.addChild(expX); + org.eclipse.persistence.expressions.Expression expY = org.eclipse.persistence.expressions.Expression.from(y, new ExpressionBuilder()); + coalesce.addChild(expY); return new CoalesceImpl(metamodel, x.getJavaType(), coalesce, buildList(x, internalLiteral(y)), "coalesce"); } @@ -2394,13 +2401,13 @@ public org.eclipse.persistence.expressions.Expression toExpression(Expression ex * that returns null if all its arguments evaluate to null, * and the value of its first non-null argument otherwise. */ - public static class CoalesceImpl extends FunctionExpressionImpl implements Coalesce{ + public class CoalesceImpl extends FunctionExpressionImpl implements Coalesce { - protected CoalesceImpl (Metamodel metamodel, Class resultClass, org.eclipse.persistence.expressions.Expression expressionNode, List> compoundExpressions){ + protected CoalesceImpl (Metamodel metamodel, Class resultClass, org.eclipse.persistence.expressions.Expression expressionNode, List> compoundExpressions) { super(metamodel, resultClass, expressionNode, compoundExpressions); } - protected CoalesceImpl (Metamodel metamodel, Class resultClass, org.eclipse.persistence.expressions.Expression expressionNode, List> compoundExpressions, String operator){ + protected CoalesceImpl (Metamodel metamodel, Class resultClass, org.eclipse.persistence.expressions.Expression expressionNode, List> compoundExpressions, String operator) { super(metamodel, resultClass, expressionNode, compoundExpressions, operator); } @@ -2410,9 +2417,11 @@ protected CoalesceImpl (Metamodel metamodel, Class resultClass, org.eclip * @return coalesce expression */ @Override - public Coalesce value(X value){ + public Coalesce value(X value) { org.eclipse.persistence.expressions.Expression exp = org.eclipse.persistence.expressions.Expression.from(value, new ExpressionBuilder()); ((FunctionExpression)currentNode).addChild(exp); + Expression valueLiteral = internalLiteral(value); + this.expressions.add(valueLiteral); return this; } @@ -2422,10 +2431,11 @@ public Coalesce value(X value){ * @return coalesce expression */ @Override - public Coalesce value(Expression value){ + public Coalesce value(Expression value) { org.eclipse.persistence.expressions.Expression exp = ((InternalSelection)value).getCurrentNode(); exp = org.eclipse.persistence.expressions.Expression.from(exp, currentNode); ((FunctionExpression)currentNode).addChild(exp); + this.expressions.add(value); return this; } } @@ -2436,13 +2446,16 @@ public Coalesce value(Expression value){ * * @param */ - public class CaseImpl extends FunctionExpressionImpl implements Case{ + public class CaseImpl extends FunctionExpressionImpl implements Case { - protected CaseImpl (Metamodel metamodel, Class resultClass, org.eclipse.persistence.expressions.Expression expressionNode, List> compoundExpressions){ + // Track the else expression separate to the when expressions as there should only be one + private Expression elseExpression; + + protected CaseImpl (Metamodel metamodel, Class resultClass, org.eclipse.persistence.expressions.Expression expressionNode, List> compoundExpressions) { super(metamodel, resultClass, expressionNode, compoundExpressions); } - protected CaseImpl (Metamodel metamodel, Class resultClass, org.eclipse.persistence.expressions.Expression expressionNode, List> compoundExpressions, String operator){ + protected CaseImpl (Metamodel metamodel, Class resultClass, org.eclipse.persistence.expressions.Expression expressionNode, List> compoundExpressions, String operator) { super(metamodel, resultClass, expressionNode, compoundExpressions, operator); } @@ -2453,13 +2466,16 @@ protected CaseImpl (Metamodel metamodel, Class resultClass, org.eclipse.p * @return general case expression */ @Override - public Case when(Expression condition, R result){ + public Case when(Expression condition, R result) { org.eclipse.persistence.expressions.Expression conditionExp = ((InternalSelection)condition).getCurrentNode(); conditionExp = org.eclipse.persistence.expressions.Expression.from(conditionExp, currentNode); ((FunctionExpression)currentNode).addChild(conditionExp); + this.expressions.add(condition); + org.eclipse.persistence.expressions.Expression resultExp = org.eclipse.persistence.expressions.Expression.from(result, new ExpressionBuilder()); ((FunctionExpression)currentNode).addChild(resultExp); Expression resultLiteral = internalLiteral(result); + this.expressions.add(resultLiteral); setJavaType((Class) resultLiteral.getJavaType()); return this; @@ -2472,13 +2488,16 @@ public Case when(Expression condition, R result){ * @return general case expression */ @Override - public Case when(Expression condition, Expression result){ + public Case when(Expression condition, Expression result) { org.eclipse.persistence.expressions.Expression conditionExp = ((InternalSelection)condition).getCurrentNode(); conditionExp = org.eclipse.persistence.expressions.Expression.from(conditionExp, currentNode); ((FunctionExpression)currentNode).addChild(conditionExp); + this.expressions.add(condition); + org.eclipse.persistence.expressions.Expression resultExp = ((InternalSelection)result).getCurrentNode(); resultExp = org.eclipse.persistence.expressions.Expression.from(resultExp, currentNode); ((FunctionExpression)currentNode).addChild(resultExp); + this.expressions.add(result); setJavaType((Class) result.getJavaType()); return this; @@ -2490,10 +2509,11 @@ public Case when(Expression condition, Expression resul * @return expression */ @Override - public Expression otherwise(R result){ - org.eclipse.persistence.expressions.Expression resultExp = org.eclipse.persistence.expressions.Expression.from(result, new ExpressionBuilder()); + public Expression otherwise(R result) { + org.eclipse.persistence.expressions.Expression resultExp = org.eclipse.persistence.expressions.Expression.from(result, new ExpressionBuilder()); ((ArgumentListFunctionExpression)currentNode).addRightMostChild(resultExp); Expression resultLiteral = internalLiteral(result); + this.elseExpression = resultLiteral; setJavaType((Class) resultLiteral.getJavaType()); return this; @@ -2505,14 +2525,23 @@ public Expression otherwise(R result){ * @return expression */ @Override - public Expression otherwise(Expression result){ + public Expression otherwise(Expression result) { org.eclipse.persistence.expressions.Expression resultExp = ((InternalSelection)result).getCurrentNode(); resultExp = org.eclipse.persistence.expressions.Expression.from(resultExp, currentNode); ((ArgumentListFunctionExpression)currentNode).addRightMostChild(resultExp); + this.elseExpression = result; setJavaType((Class) result.getJavaType()); return this; } + + @Override + public void findRootAndParameters(CommonAbstractCriteriaImpl query) { + super.findRootAndParameters(query); + if (this.elseExpression != null){ + ((InternalSelection)elseExpression).findRootAndParameters(query); + } + } } /** @@ -2522,17 +2551,20 @@ public Expression otherwise(Expression result){ * @param * @param */ - public class SimpleCaseImpl extends FunctionExpressionImpl implements SimpleCase{ + public class SimpleCaseImpl extends FunctionExpressionImpl implements SimpleCase { private Expression expression; - protected SimpleCaseImpl (Metamodel metamodel, Class resultClass, FunctionExpression expressionNode, List> compoundExpressions, Expression expression){ + // Track the else expression separate to the when expressions as there should only be one + private Expression elseExpression; + + protected SimpleCaseImpl (Metamodel metamodel, Class resultClass, FunctionExpression expressionNode, List> compoundExpressions, Expression expression) { super(metamodel, resultClass, expressionNode, compoundExpressions); this.expression = expression; expressionNode.addChild(((InternalSelection)expression).getCurrentNode()); } - protected SimpleCaseImpl (Metamodel metamodel, Class resultClass, FunctionExpression expressionNode, List> compoundExpressions, String operator, Expression expression){ + protected SimpleCaseImpl (Metamodel metamodel, Class resultClass, FunctionExpression expressionNode, List> compoundExpressions, String operator, Expression expression) { super(metamodel, resultClass, expressionNode, compoundExpressions, operator); this.expression = expression; expressionNode.addChild(((InternalSelection)expression).getCurrentNode()); @@ -2558,9 +2590,13 @@ public Expression getExpression(){ public SimpleCase when(C condition, R result){ org.eclipse.persistence.expressions.Expression conditionExp = org.eclipse.persistence.expressions.Expression.from(condition, new ExpressionBuilder()); ((FunctionExpression)currentNode).addChild(conditionExp); + Expression conditionLiteral = internalLiteral(condition); + this.expressions.add(conditionLiteral); + org.eclipse.persistence.expressions.Expression resultExp = org.eclipse.persistence.expressions.Expression.from(result, new ExpressionBuilder()); ((FunctionExpression)currentNode).addChild(resultExp); Expression resultLiteral = internalLiteral(result); + this.expressions.add(resultLiteral); setJavaType((Class) resultLiteral.getJavaType()); return this; @@ -2573,12 +2609,16 @@ public SimpleCase when(C condition, R result){ * @return simple case expression */ @Override - public SimpleCase when(C condition, Expression result){ + public SimpleCase when(C condition, Expression result) { org.eclipse.persistence.expressions.Expression conditionExp = org.eclipse.persistence.expressions.Expression.from(condition, new ExpressionBuilder()); ((FunctionExpression)currentNode).addChild(conditionExp); + Expression conditionLiteral = internalLiteral(condition); + this.expressions.add(conditionLiteral); + org.eclipse.persistence.expressions.Expression resultExp = ((InternalSelection)result).getCurrentNode(); resultExp = org.eclipse.persistence.expressions.Expression.from(resultExp, currentNode); ((FunctionExpression)currentNode).addChild(resultExp); + this.expressions.add(result); setJavaType((Class) result.getJavaType()); return this; @@ -2590,10 +2630,11 @@ public SimpleCase when(C condition, Expression result){ * @return expression */ @Override - public Expression otherwise(R result){ + public Expression otherwise(R result) { org.eclipse.persistence.expressions.Expression resultExp = org.eclipse.persistence.expressions.Expression.from(result, new ExpressionBuilder()); ((ArgumentListFunctionExpression)currentNode).addRightMostChild(resultExp); Expression resultLiteral = internalLiteral(result); + this.elseExpression = resultLiteral; setJavaType((Class) resultLiteral.getJavaType()); return this; @@ -2605,14 +2646,26 @@ public Expression otherwise(R result){ * @return expression */ @Override - public Expression otherwise(Expression result){ + public Expression otherwise(Expression result) { org.eclipse.persistence.expressions.Expression resultExp = ((InternalSelection)result).getCurrentNode(); resultExp = org.eclipse.persistence.expressions.Expression.from(resultExp, currentNode); ((ArgumentListFunctionExpression)currentNode).addRightMostChild(resultExp); + this.elseExpression = result; setJavaType((Class) result.getJavaType()); return this; } + + @Override + public void findRootAndParameters(CommonAbstractCriteriaImpl query) { + super.findRootAndParameters(query); + if(expression != null) { + ((InternalSelection)expression).findRootAndParameters(query); + } + if (this.elseExpression != null){ + ((InternalSelection)elseExpression).findRootAndParameters(query); + } + } } @Override