diff --git a/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/jpa/jpql/JPQLFunctionsAbstractBuilder.java b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/jpa/jpql/JPQLFunctionsAbstractBuilder.java index 90e3c118458..c96960a0573 100644 --- a/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/jpa/jpql/JPQLFunctionsAbstractBuilder.java +++ b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/jpa/jpql/JPQLFunctionsAbstractBuilder.java @@ -63,13 +63,26 @@ public void visit(IdExpression expression) { //Get id attribute name ClassDescriptor descriptor = this.queryContext.getDeclaration(variableName).getDescriptor(); List primaryKeyFields = descriptor.getPrimaryKeyFields(); - String idAttributeName = getIdAttributeNameByField(descriptor.getMappings(), primaryKeyFields.get(0)); - StateFieldPathExpression stateFieldPathExpression = new StateFieldPathExpression(expression.getParent(), variableText + "." + idAttributeName); - expression.setStateFieldPathExpression(stateFieldPathExpression); + if (!isEmbeddable(descriptor.getMappings())) { + for (DatabaseField primaryKeyField : primaryKeyFields) { + String idAttributeName = getIdAttributeNameByField(descriptor.getMappings(), primaryKeyField); + StateFieldPathExpression stateFieldPathExpression = new StateFieldPathExpression( + expression.getParent(), variableText + "." + idAttributeName); + expression.setStateFieldPathExpression(stateFieldPathExpression); + // Continue with created StateFieldPathExpression + // It handle by ObjectBuilder booth @Id/primary key types (simple/composite) + expression.getStateFieldPathExpression().accept(this); + } + } else { + String idAttributeName = getIdAttributeNameByField(descriptor.getMappings(), primaryKeyFields.get(0)); + StateFieldPathExpression stateFieldPathExpression = new StateFieldPathExpression( + expression.getParent(), variableText + "." + idAttributeName); + expression.setStateFieldPathExpression(stateFieldPathExpression); + // Continue with created StateFieldPathExpression + // It handle by ObjectBuilder booth @Id/primary key types (simple/composite) + expression.getStateFieldPathExpression().accept(this); - //Continue with created StateFieldPathExpression - //It handle by ObjectBuilder booth @Id/primary key types (simple/composite) - expression.getStateFieldPathExpression().accept(this); + } } /** @@ -96,10 +109,24 @@ public void visit(VersionExpression expression) { private String getIdAttributeNameByField(List databaseMappings, DatabaseField field) { for (DatabaseMapping mapping : databaseMappings) { - if (field.equals(mapping.getField()) || mapping.isPrimaryKeyMapping()) { + if (mapping.getFields().size() > 1 && (field.equals(mapping.getField()) || mapping.isPrimaryKeyMapping())) { return mapping.getAttributeName(); + } else { + if ((field.equals(mapping.getField()) && mapping.isPrimaryKeyMapping())) { + return mapping.getAttributeName(); + } } } return null; } + + private boolean isEmbeddable(List databaseMappings) { + + for (DatabaseMapping databaseMapping : databaseMappings) { + if (databaseMapping.isPrimaryKeyMapping() && databaseMapping.getFields().size() > 1) { + return true; + } + } + return false; + } } diff --git a/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/jpa/jpql/ReportItemBuilder.java b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/jpa/jpql/ReportItemBuilder.java index 0e78b8e05d0..6d23c32ddd8 100644 --- a/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/jpa/jpql/ReportItemBuilder.java +++ b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/jpa/jpql/ReportItemBuilder.java @@ -41,6 +41,7 @@ import org.eclipse.persistence.jpa.jpql.parser.EntryExpression; import org.eclipse.persistence.jpa.jpql.parser.ExtractExpression; import org.eclipse.persistence.jpa.jpql.parser.FunctionExpression; +import org.eclipse.persistence.jpa.jpql.parser.IdExpression; import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariable; import org.eclipse.persistence.jpa.jpql.parser.IndexExpression; import org.eclipse.persistence.jpa.jpql.parser.Join; @@ -630,7 +631,7 @@ private void visitAbstractSelectClause(AbstractSelectClause expression) { multipleSelects = false; expression.getSelectExpression().accept(this); - if (multipleSelects) { + if (multipleSelects || (expression.getSelectExpression() instanceof IdExpression)) { query.returnWithoutReportQueryResult(); } else { diff --git a/jpa/eclipselink.jpa.testapps/jpa.test.jpql/src/test/java/org/eclipse/persistence/testing/tests/jpa/jpql/advanced/compositepk/JUnitJPQLComplexAggregateTest.java b/jpa/eclipselink.jpa.testapps/jpa.test.jpql/src/test/java/org/eclipse/persistence/testing/tests/jpa/jpql/advanced/compositepk/JUnitJPQLComplexAggregateTest.java index f87ec1c69a4..eea1054e626 100644 --- a/jpa/eclipselink.jpa.testapps/jpa.test.jpql/src/test/java/org/eclipse/persistence/testing/tests/jpa/jpql/advanced/compositepk/JUnitJPQLComplexAggregateTest.java +++ b/jpa/eclipselink.jpa.testapps/jpa.test.jpql/src/test/java/org/eclipse/persistence/testing/tests/jpa/jpql/advanced/compositepk/JUnitJPQLComplexAggregateTest.java @@ -24,6 +24,7 @@ import org.eclipse.persistence.testing.models.jpa.advanced.compositepk.CompositePKTableCreator; import org.eclipse.persistence.testing.models.jpa.advanced.compositepk.Cubicle; import org.eclipse.persistence.testing.models.jpa.advanced.compositepk.Scientist; +import org.eclipse.persistence.testing.models.jpa.advanced.compositepk.ScientistPK; import org.junit.Assert; import java.util.Arrays; @@ -60,7 +61,7 @@ public static Test suite() { suite.addTest(new JUnitJPQLComplexAggregateTest("testSetup")); suite.addTest(new JUnitJPQLComplexAggregateTest("complexCountOnJoinedCompositePK")); - + suite.addTest(new JUnitJPQLComplexAggregateTest("testCompositePrimaryKey")); return suite; } @@ -121,4 +122,53 @@ public void complexCountOnJoinedCompositePK() { } } + public void testCompositePrimaryKey() { + EntityManager em = createEntityManager(); + try { + // Start the transaction + beginTransaction(em); + + // Create and set up the Scientist and Cubicle entities + Scientist scientist = new Scientist(); + scientist.setFirstName("John"); + scientist.setLastName("Doe"); + + Cubicle cubicle = new Cubicle(); + cubicle.setCode("G"); + cubicle.setScientist(scientist); + + scientist.setCubicle(cubicle); + + // Persist the entities + em.persist(cubicle); + em.persist(scientist); + em.flush(); + + // Execute the query to retrieve the primary keys + List keys = em.createQuery( + "SELECT ID(THIS) FROM Scientist WHERE firstName = :firstName ORDER BY idNumber", + ScientistPK.class + ) + .setParameter("firstName", "John") + .getResultList(); + + // Ensure the result size is greater than 0 + assertTrue("The result size should be greater than 0", !keys.isEmpty()); + + } catch (Exception e) { + // If there's an exception, rollback the transaction + rollbackTransaction(em); + throw e; + } finally { + // Ensure the transaction is rolled back if not committed + if (em.getTransaction().isActive()) { + rollbackTransaction(em); + } + // Close the entity manager + em.close(); + } +} + + + }