Skip to content

Commit

Permalink
Jakarta Persistence 3.2: fix for JPQL with generated this alias in @N…
Browse files Browse the repository at this point in the history
…amedQuery (eclipse-ee4j#2360)

Fixes eclipse-ee4j#2253 . Before this fix, different parser validation settings (more strict) were applied to JPQL queries stored in `@NamedQuery`, than JPQL queries created by `em.createQuery(...)`.

Signed-off-by: Radek Felcman <[email protected]>
  • Loading branch information
rfelcman authored Feb 17, 2025
1 parent b22880e commit b1837bd
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, 2024 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2025 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024 Contributors to the Eclipse Foundation. All rights reserved.
*
* This program and the accompanying materials are made available under the
Expand Down Expand Up @@ -276,19 +276,7 @@ private DatabaseQuery populateQueryImp(CharSequence jpqlQuery,
AbstractSession session) {

try {
String version = Version.getVersion();
String majorMinorVersion = version.substring(0, version.indexOf(".", version.indexOf(".") + 1));
EclipseLinkVersion elVersion = EclipseLinkVersion.value(majorMinorVersion);
boolean isJakartaDataVersion = elVersion.isNewerThanOrEqual(EclipseLinkVersion.VERSION_5_0) || isJakartaDataValidationLevel();
// Parse the JPQL query with the most recent JPQL grammar
JPQLExpression jpqlExpression = new JPQLExpression(
jpqlQuery,
DefaultEclipseLinkJPQLGrammar.instance(),
JPQLStatementBNF.ID,
isTolerant(),
isJakartaDataVersion
);

JPQLExpression jpqlExpression = buildJPQLExpression(jpqlQuery);
// Create a context that caches the information contained in the JPQL query
// (especially from the FROM clause)
JPQLQueryContext queryContext = new JPQLQueryContext(jpqlGrammar());
Expand Down Expand Up @@ -467,4 +455,20 @@ public void visit(UpdateStatement expression) {
expression.accept(visitor);
}
}

JPQLExpression buildJPQLExpression(CharSequence jpqlQuery) {
String version = Version.getVersion();
String majorMinorVersion = version.substring(0, version.indexOf(".", version.indexOf(".") + 1));
EclipseLinkVersion elVersion = EclipseLinkVersion.value(majorMinorVersion);
boolean isJakartaDataVersion = elVersion.isNewerThanOrEqual(EclipseLinkVersion.VERSION_5_0) || isJakartaDataValidationLevel();
// Parse the JPQL query with the most recent JPQL grammar
JPQLExpression jpqlExpression = new JPQLExpression(
jpqlQuery,
DefaultEclipseLinkJPQLGrammar.instance(),
JPQLStatementBNF.ID,
isTolerant(),
isJakartaDataVersion
);
return jpqlExpression;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2025 Oracle and/or its affiliates. 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
Expand All @@ -14,6 +14,7 @@
// Oracle - initial API and implementation
package org.eclipse.persistence.internal.jpa.jpql;

import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.jpa.jpql.Assert;
Expand Down Expand Up @@ -79,7 +80,9 @@ public JPQLQueryHelper(JPQLGrammar jpqlGrammar) {
public List<ClassDescriptor> getClassDescriptors(CharSequence jpqlQuery, AbstractSession session) {

// Parse the JPQL query
JPQLExpression jpqlExpression = new JPQLExpression(jpqlQuery, jpqlGrammar, true);
HermesParser hermesParser = new HermesParser();
hermesParser.setValidationLevel((String)session.getProperty(PersistenceUnitProperties.JPQL_VALIDATION));
JPQLExpression jpqlExpression = hermesParser.buildJPQLExpression(jpqlQuery);

// Create the context and cache the information
JPQLQueryContext queryContext = new JPQLQueryContext(jpqlGrammar);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2022 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2025 Oracle and/or its affiliates. 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
Expand All @@ -18,6 +18,8 @@
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.NamedQueries;
import jakarta.persistence.NamedQuery;
import jakarta.persistence.Table;
import jakarta.persistence.TableGenerator;

Expand All @@ -28,6 +30,9 @@

@Entity
@Table(name = "CMP3_WRAPPER_TYPES")
@NamedQueries({
@NamedQuery(name = "WrapperTypes.noAliasFindById", query = "FROM WrapperTypes WHERE id = :idParam")
})
public class WrapperTypes implements java.io.Serializable {

private int id;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024, 2025 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024 Contributors to the Eclipse Foundation. All rights reserved
*
* This program and the accompanying materials are made available under the
Expand Down Expand Up @@ -107,6 +107,7 @@ public static Test suite() {
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testNoAliasWhereWithBraces02"));
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testNoAliasWhereWithBraces03"));
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testGeneratedSelectNoAliasFromWhere"));
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testGeneratedSelectNoAliasFromWhere_NamedQuery"));
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testGeneratedSelect"));
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testUpdateQueryLengthInAssignmentAndExpression"));
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testSelectQueryLengthInAssignmentAndExpression"));
Expand Down Expand Up @@ -323,6 +324,21 @@ public void testGeneratedSelectNoAliasFromWhere() {
Assert.assertTrue("GeneratedSelectNoAliasFromWhere Test Failed", comparer.compareObjects(wrapperTypes, tlWrapperTypes));
}


public void testGeneratedSelectNoAliasFromWhere_NamedQuery() {
EntityManager em = createEntityManager();
Query wrapperTypesQuery = em.createNamedQuery("WrapperTypes.noAliasFindById");
wrapperTypesQuery.setParameter("idParam", wrapperId);
WrapperTypes wrapperTypes = (WrapperTypes) wrapperTypesQuery.getResultList().get(0);
clearCache();
ReadObjectQuery tlQuery = new ReadObjectQuery(WrapperTypes.class);
tlQuery.setSelectionCriteria(tlQuery.getExpressionBuilder().get("id").equal(wrapperId));

WrapperTypes tlWrapperTypes = (WrapperTypes) getPersistenceUnitServerSession().executeQuery(tlQuery);
Assert.assertTrue("GeneratedSelectNoAliasFromWhere Test Failed", comparer.compareObjects(wrapperTypes, tlWrapperTypes));
}


public void testUpdateQueryLengthInAssignmentAndExpression() {
resetRooms(false);
long numberOfChanges = getEntityManagerFactory().callInTransaction(em -> em.createQuery(
Expand Down

0 comments on commit b1837bd

Please sign in to comment.