Skip to content

Commit ec0c9cd

Browse files
authored
Enum attribute in JPQL is broken when entity identifier is omitted or is 'this.' - bugfix and unit tests (#2268)
Fixes #2185 Signed-off-by: Radek Felcman <[email protected]>
1 parent 4a7149f commit ec0c9cd

File tree

5 files changed

+96
-8
lines changed

5 files changed

+96
-8
lines changed

jpa/eclipselink.jpa.testapps/jpa.test.advanced/src/main/java/org/eclipse/persistence/testing/models/jpa/advanced/AdvancedTableCreator.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
* Copyright (c) 1998, 2022 Oracle and/or its affiliates. All rights reserved.
3-
* Copyright (c) 1998, 2022 IBM Corporation. All rights reserved.
2+
* Copyright (c) 1998, 2024 Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 1998, 2024 IBM Corporation. All rights reserved.
44
*
55
* This program and the accompanying materials are made available under the
66
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -2656,6 +2656,16 @@ public TableDefinition buildCMP3_ROOMTable() {
26562656
fieldHEIGHT.setShouldAllowNull(true);
26572657
table.addField(fieldHEIGHT);
26582658

2659+
FieldDefinition fieldSTATUS = new FieldDefinition();
2660+
fieldSTATUS.setName("STATUS");
2661+
fieldSTATUS.setTypeName("VARCHAR");
2662+
fieldSTATUS.setSize(32);
2663+
fieldSTATUS.setIsPrimaryKey(false);
2664+
fieldSTATUS.setIsIdentity(false);
2665+
fieldSTATUS.setUnique(false);
2666+
fieldSTATUS.setShouldAllowNull(true);
2667+
table.addField(fieldSTATUS);
2668+
26592669
return table;
26602670
}
26612671

jpa/eclipselink.jpa.testapps/jpa.test.advanced/src/main/java/org/eclipse/persistence/testing/models/jpa/advanced/Room.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,33 @@
4343
})
4444
})
4545
public class Room implements Serializable, Cloneable {
46+
47+
public enum Status {
48+
FREE, OCCUPIED;
49+
}
50+
4651
@Id
4752
private int id;
4853
private int width;
4954
private int length;
5055
private int height;
56+
private Status status;
5157

5258
@OneToMany(mappedBy="room", cascade=CascadeType.ALL, fetch=FetchType.LAZY)
5359
private Collection<Door> doors;
5460

61+
public Room() {
62+
}
63+
64+
public Room(int id, int width, int length, int height, Status status) {
65+
this.id = id;
66+
this.width = width;
67+
this.length = length;
68+
this.height = height;
69+
this.status = status;
70+
this.doors = doors;
71+
}
72+
5573
public int getId() {
5674
return id;
5775
}
@@ -84,6 +102,14 @@ public void setHeight(int height) {
84102
this.height = height;
85103
}
86104

105+
public Status getStatus() {
106+
return status;
107+
}
108+
109+
public void setStatus(Status status) {
110+
this.status = status;
111+
}
112+
87113
public Collection<Door> getDoors() {
88114
return doors;
89115
}

jpa/eclipselink.jpa.testapps/jpa.test.jpql/src/test/java/org/eclipse/persistence/testing/tests/jpa/jpql/advanced/JUnitJPQLJakartaDataNoAliasTest.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ public class JUnitJPQLJakartaDataNoAliasTest extends JUnitTestCase {
5555
private static final String STRING_DATA_LIKE_EXPRESSION = "A%"; // should match STRING_DATA
5656
private static final Room[] ROOMS = new Room[]{
5757
null, // Skip array index 0
58-
aRoom(1, 1, 1, 1),
59-
aRoom(2, 1, 1, 1),
60-
aRoom(3, 1, 1, 1),
61-
aRoom(4, 1, 1, 1)
58+
aRoom(1, 1, 1, 1, Room.Status.FREE),
59+
aRoom(2, 1, 1, 1, Room.Status.FREE),
60+
aRoom(3, 1, 1, 1, Room.Status.OCCUPIED),
61+
aRoom(4, 1, 1, 1, Room.Status.OCCUPIED)
6262
};
6363
private static final long ROOMS_COUNT = ROOMS.length - 1; // we ignore the first one with index 0
6464

@@ -110,6 +110,7 @@ public static Test suite() {
110110
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testSelectQueryImplicitThisVariableInPath"));
111111
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testSelectQueryImplicitThisVariableInAggregateFunctionPath"));
112112
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testSelectQueryImplicitThisVariableInArithmeticExpression"));
113+
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testSelectQueryImplicitThisVariableAndEnum"));
113114
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testUpdateImplicitVariableInArithmeticExpression"));
114115
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testDeleteQueryLengthInExpressionOnLeft"));
115116
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testDeleteQueryLengthInExpressionOnRight"));
@@ -367,6 +368,20 @@ public void testSelectQueryImplicitThisVariableInArithmeticExpression() {
367368
assertEquals(ROOMS[1].getLength() * ROOMS[1].getWidth() * ROOMS[1].getHeight(), roomCapacity);
368369
}
369370

371+
// Covers https://github.com/eclipse-ee4j/eclipselink/issues/2185
372+
public void testSelectQueryImplicitThisVariableAndEnum() {
373+
resetRooms();
374+
List<Room> rooms = getEntityManagerFactory().callInTransaction(em -> em.createQuery(
375+
"SELECT NEW org.eclipse.persistence.testing.models.jpa.advanced.Room(id, width, length, height, status) " +
376+
"FROM Room " +
377+
"WHERE id = :idParam AND status=org.eclipse.persistence.testing.models.jpa.advanced.Room.Status.FREE " +
378+
"ORDER BY width DESC, id ASC",
379+
Room.class)
380+
.setParameter("idParam", ROOMS[1].getId())
381+
.getResultList());
382+
assertEquals(ROOMS[1], rooms.get(0));
383+
}
384+
370385
public void testUpdateImplicitVariableInArithmeticExpression() {
371386
resetRooms();
372387
int numberOfChanges = getEntityManagerFactory().callInTransaction(em -> em.createQuery(
@@ -466,12 +481,13 @@ private Room findRoomById(int i) {
466481
});
467482
}
468483

469-
private static Room aRoom(int id, int width, int length, int height) {
484+
private static Room aRoom(int id, int width, int length, int height, Room.Status status) {
470485
Room room = new Room();
471486
room.setId(id);
472487
room.setWidth(width);
473488
room.setLength(length);
474489
room.setHeight(height);
490+
room.setStatus(status);
475491
return room;
476492
}
477493

jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractPathExpression.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ else if (!identificationVariable.isNull() &&
212212
identificationVariable = buildNullExpression();
213213
}
214214
else {
215-
identificationVariable = new IdentificationVariable(this, paths.get(0));
215+
identificationVariable = new IdentificationVariable(this, paths.get(0), false);
216216
}
217217
}
218218
}

jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLExpressionTestJakartaData.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@
2525
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.inputParameter;
2626
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.isNotNull;
2727
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.max;
28+
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.new_;
2829
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.numeric;
30+
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.orderBy;
31+
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.orderByItemAsc;
32+
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.orderByItemDesc;
2933
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.path;
3034
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.select;
3135
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.selectStatement;
@@ -238,6 +242,38 @@ public void testFunctionNameAsImplicitStateFieldInSelectArithmeticExpression() {
238242
testJakartaDataQuery(inputJPQLQuery, selectStatement);
239243
}
240244

245+
// Covers https://github.com/eclipse-ee4j/eclipselink/issues/2185
246+
@Test
247+
public void testSelectWithImplicitThisAliasAndEnum() {
248+
249+
String inputJPQLQuery = "SELECT NEW com.oracle.jpa.bugtest.Rebate(id, amount, customerId, purchaseMadeAt, purchaseMadeOn, status, updatedAt, version) " +
250+
"FROM Rebate " +
251+
"WHERE customerId=:customerIdParam AND status=com.oracle.jpa.bugtest.Rebate.Status.PAID " +
252+
"ORDER BY amount DESC, id ASC";
253+
254+
SelectStatementTester selectStatement = selectStatement(
255+
select(
256+
new_(
257+
"com.oracle.jpa.bugtest.Rebate",
258+
virtualVariable("this", "id"),
259+
virtualVariable("this", "amount"),
260+
virtualVariable("this", "customerId"),
261+
virtualVariable("this", "purchaseMadeAt"),
262+
virtualVariable("this", "purchaseMadeOn"),
263+
virtualVariable("this", "status"),
264+
virtualVariable("this", "updatedAt"),
265+
virtualVariable("this", "version")
266+
)
267+
),
268+
from("Rebate", "{this}"),
269+
where(and(equal(virtualVariable("this", "customerId"), inputParameter(":customerIdParam")),
270+
equal(virtualVariable("this", "status"), path("com.oracle.jpa.bugtest.Rebate.Status.PAID")))),
271+
orderBy(orderByItemDesc(virtualVariable("this", "amount")), orderByItemAsc(virtualVariable("this", "id")))
272+
);
273+
274+
testJakartaDataQuery(inputJPQLQuery, selectStatement);
275+
}
276+
241277
@Test
242278
public void testUpdateFunctionNameAsImplicitStateFieldInNumericExpression() {
243279

0 commit comments

Comments
 (0)