diff --git a/jpa/eclipselink.jpa.testapps/jpa.test.persistence32/src/test/java/org/eclipse/persistence/testing/tests/jpa/persistence32/UnionCriteriaQueryTest.java b/jpa/eclipselink.jpa.testapps/jpa.test.persistence32/src/test/java/org/eclipse/persistence/testing/tests/jpa/persistence32/UnionCriteriaQueryTest.java index 4ec968f5856..96bd487c21c 100644 --- a/jpa/eclipselink.jpa.testapps/jpa.test.persistence32/src/test/java/org/eclipse/persistence/testing/tests/jpa/persistence32/UnionCriteriaQueryTest.java +++ b/jpa/eclipselink.jpa.testapps/jpa.test.persistence32/src/test/java/org/eclipse/persistence/testing/tests/jpa/persistence32/UnionCriteriaQueryTest.java @@ -59,6 +59,7 @@ public static Test suite() { new UnionCriteriaQueryTest("testExceptAllWithNoSelection"), new UnionCriteriaQueryTest("testUnionWithEntityParameterInSelection"), new UnionCriteriaQueryTest("testUnionWithMultiselectEntityParametersInSelection"), + new UnionCriteriaQueryTest("testUnionWithMultiselectEntityParametersInSelectionResultTypePartial"), new UnionCriteriaQueryTest("testUnionWithMultiselectEntityInSelection") ); } @@ -415,8 +416,37 @@ public void testUnionWithMultiselectEntityParametersInSelection() { } } - // TODO testUnionWithMultiselectEntityParametersInSelection without supporting constructor - // to validate ResultType.PARTIAL with compound query + // Selects partial content of existing Trainer constructor prototype + // This shall trigger compound query builder with ResultType.PARTIAL. + @SuppressWarnings("deprecation") + public void testUnionWithMultiselectEntityParametersInSelectionResultTypePartial() { + try (EntityManager em = emf.createEntityManager()) { + EntityTransaction et = em.getTransaction(); + try { + et.begin(); + CriteriaBuilder cb = em.getCriteriaBuilder(); + + CriteriaQuery q1 = cb.createQuery(Trainer.class); + Root root1 = q1.from(Trainer.class); + q1.multiselect(root1.get("id"), root1.get("name")); + q1.where(cb.equal(root1.get("name"), cb.parameter(String.class, "name1"))); + + CriteriaQuery q2 = cb.createQuery(Trainer.class); + Root root2 = q2.from(Trainer.class); + q2.multiselect(root2.get("id"), root2.get("name")); + q2.where(cb.equal(root2.get("name"), cb.parameter(String.class, "name2"))); + + TypedQuery query = em.createQuery(cb.union(q1, q2)); + query.setParameter("name1", TRAINERS[1].getName()); + query.setParameter("name2", TRAINERS[2].getName()); + List trainers = query.getResultList(); + assertEquals(2, trainers.size()); + } catch (Exception e) { + et.rollback(); + throw e; + } + } + } public void testUnionWithMultiselectEntityInSelection() { try (EntityManager em = emf.createEntityManager()) { diff --git a/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/querydef/CriteriaQueryImpl.java b/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/querydef/CriteriaQueryImpl.java index 462fe1e7e86..338ed3c6fb2 100644 --- a/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/querydef/CriteriaQueryImpl.java +++ b/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/querydef/CriteriaQueryImpl.java @@ -498,20 +498,21 @@ protected ReadAllQuery createCompoundQuery(boolean toReportQuery) { if (this.queryResult.equals(ResultType.PARTIAL)) { ReadAllQuery raq; - // TODO: allow force of ReportQuery creation for usage in UNION - // TODO: In progress, code is not working and tested !!! - // See testUnionWithMultiselectEntityParametersInSelection TODO in UnionCriteriaQueryTest + @SuppressWarnings("unchecked") + List> selectionItems = (List>) (List) this.selection.getCompoundSelectionItems(); if (toReportQuery) { - //raq = createReportQuery(this.queryType); - raq = createReportQueryWithItem(this.queryType); + raq = createReportQuery(this.queryType); + for (SelectionImpl nested : selectionItems) { + ((ReportQuery) raq).addAttribute(nested.getAlias(), nested.getCurrentNode(), nested.getJavaType()); + } } else { raq = new ReadAllQuery(this.queryType); } - // TODO: double check whether this may be avoided + // Partial object queries are not allowed to maintain the cache or be edited. Requires dontMaintainCache(). + // See hasPartialAttributeExpressions() in ObjectLevelReadQuery#prepareQuery() raq.dontMaintainCache(); - // TODO: ROOTS? - for (Selection selection : this.selection.getCompoundSelectionItems()) { - raq.addPartialAttribute(((SelectionImpl) selection).currentNode); + for (SelectionImpl selection : selectionItems) { + raq.addPartialAttribute((selection).currentNode); } raq.setExpressionBuilder(((InternalSelection) this.selection.getCompoundSelectionItems().get(0)).getCurrentNode().getBuilder()); query = raq;