Skip to content

Commit

Permalink
Enum attribute in JPQL is broken when entity identifier is omitted or…
Browse files Browse the repository at this point in the history
… is 'this.' - bugfix and unit tests (#2268)

Fixes #2185

Signed-off-by: Radek Felcman <[email protected]>
  • Loading branch information
rfelcman authored Sep 24, 2024
1 parent 4a7149f commit ec0c9cd
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 1998, 2022 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2022 IBM Corporation. All rights reserved.
* Copyright (c) 1998, 2024 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2024 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
Expand Down Expand Up @@ -2656,6 +2656,16 @@ public TableDefinition buildCMP3_ROOMTable() {
fieldHEIGHT.setShouldAllowNull(true);
table.addField(fieldHEIGHT);

FieldDefinition fieldSTATUS = new FieldDefinition();
fieldSTATUS.setName("STATUS");
fieldSTATUS.setTypeName("VARCHAR");
fieldSTATUS.setSize(32);
fieldSTATUS.setIsPrimaryKey(false);
fieldSTATUS.setIsIdentity(false);
fieldSTATUS.setUnique(false);
fieldSTATUS.setShouldAllowNull(true);
table.addField(fieldSTATUS);

return table;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,33 @@
})
})
public class Room implements Serializable, Cloneable {

public enum Status {
FREE, OCCUPIED;
}

@Id
private int id;
private int width;
private int length;
private int height;
private Status status;

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

public Room() {
}

public Room(int id, int width, int length, int height, Status status) {
this.id = id;
this.width = width;
this.length = length;
this.height = height;
this.status = status;
this.doors = doors;
}

public int getId() {
return id;
}
Expand Down Expand Up @@ -84,6 +102,14 @@ public void setHeight(int height) {
this.height = height;
}

public Status getStatus() {
return status;
}

public void setStatus(Status status) {
this.status = status;
}

public Collection<Door> getDoors() {
return doors;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ public class JUnitJPQLJakartaDataNoAliasTest extends JUnitTestCase {
private static final String STRING_DATA_LIKE_EXPRESSION = "A%"; // should match STRING_DATA
private static final Room[] ROOMS = new Room[]{
null, // Skip array index 0
aRoom(1, 1, 1, 1),
aRoom(2, 1, 1, 1),
aRoom(3, 1, 1, 1),
aRoom(4, 1, 1, 1)
aRoom(1, 1, 1, 1, Room.Status.FREE),
aRoom(2, 1, 1, 1, Room.Status.FREE),
aRoom(3, 1, 1, 1, Room.Status.OCCUPIED),
aRoom(4, 1, 1, 1, Room.Status.OCCUPIED)
};
private static final long ROOMS_COUNT = ROOMS.length - 1; // we ignore the first one with index 0

Expand Down Expand Up @@ -110,6 +110,7 @@ public static Test suite() {
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testSelectQueryImplicitThisVariableInPath"));
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testSelectQueryImplicitThisVariableInAggregateFunctionPath"));
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testSelectQueryImplicitThisVariableInArithmeticExpression"));
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testSelectQueryImplicitThisVariableAndEnum"));
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testUpdateImplicitVariableInArithmeticExpression"));
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testDeleteQueryLengthInExpressionOnLeft"));
suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testDeleteQueryLengthInExpressionOnRight"));
Expand Down Expand Up @@ -367,6 +368,20 @@ public void testSelectQueryImplicitThisVariableInArithmeticExpression() {
assertEquals(ROOMS[1].getLength() * ROOMS[1].getWidth() * ROOMS[1].getHeight(), roomCapacity);
}

// Covers https://github.com/eclipse-ee4j/eclipselink/issues/2185
public void testSelectQueryImplicitThisVariableAndEnum() {
resetRooms();
List<Room> rooms = getEntityManagerFactory().callInTransaction(em -> em.createQuery(
"SELECT NEW org.eclipse.persistence.testing.models.jpa.advanced.Room(id, width, length, height, status) " +
"FROM Room " +
"WHERE id = :idParam AND status=org.eclipse.persistence.testing.models.jpa.advanced.Room.Status.FREE " +
"ORDER BY width DESC, id ASC",
Room.class)
.setParameter("idParam", ROOMS[1].getId())
.getResultList());
assertEquals(ROOMS[1], rooms.get(0));
}

public void testUpdateImplicitVariableInArithmeticExpression() {
resetRooms();
int numberOfChanges = getEntityManagerFactory().callInTransaction(em -> em.createQuery(
Expand Down Expand Up @@ -466,12 +481,13 @@ private Room findRoomById(int i) {
});
}

private static Room aRoom(int id, int width, int length, int height) {
private static Room aRoom(int id, int width, int length, int height, Room.Status status) {
Room room = new Room();
room.setId(id);
room.setWidth(width);
room.setLength(length);
room.setHeight(height);
room.setStatus(status);
return room;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ else if (!identificationVariable.isNull() &&
identificationVariable = buildNullExpression();
}
else {
identificationVariable = new IdentificationVariable(this, paths.get(0));
identificationVariable = new IdentificationVariable(this, paths.get(0), false);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.inputParameter;
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.isNotNull;
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.max;
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.new_;
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.numeric;
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.orderBy;
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.orderByItemAsc;
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.orderByItemDesc;
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.path;
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.select;
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.selectStatement;
Expand Down Expand Up @@ -238,6 +242,38 @@ public void testFunctionNameAsImplicitStateFieldInSelectArithmeticExpression() {
testJakartaDataQuery(inputJPQLQuery, selectStatement);
}

// Covers https://github.com/eclipse-ee4j/eclipselink/issues/2185
@Test
public void testSelectWithImplicitThisAliasAndEnum() {

String inputJPQLQuery = "SELECT NEW com.oracle.jpa.bugtest.Rebate(id, amount, customerId, purchaseMadeAt, purchaseMadeOn, status, updatedAt, version) " +
"FROM Rebate " +
"WHERE customerId=:customerIdParam AND status=com.oracle.jpa.bugtest.Rebate.Status.PAID " +
"ORDER BY amount DESC, id ASC";

SelectStatementTester selectStatement = selectStatement(
select(
new_(
"com.oracle.jpa.bugtest.Rebate",
virtualVariable("this", "id"),
virtualVariable("this", "amount"),
virtualVariable("this", "customerId"),
virtualVariable("this", "purchaseMadeAt"),
virtualVariable("this", "purchaseMadeOn"),
virtualVariable("this", "status"),
virtualVariable("this", "updatedAt"),
virtualVariable("this", "version")
)
),
from("Rebate", "{this}"),
where(and(equal(virtualVariable("this", "customerId"), inputParameter(":customerIdParam")),
equal(virtualVariable("this", "status"), path("com.oracle.jpa.bugtest.Rebate.Status.PAID")))),
orderBy(orderByItemDesc(virtualVariable("this", "amount")), orderByItemAsc(virtualVariable("this", "id")))
);

testJakartaDataQuery(inputJPQLQuery, selectStatement);
}

@Test
public void testUpdateFunctionNameAsImplicitStateFieldInNumericExpression() {

Expand Down

0 comments on commit ec0c9cd

Please sign in to comment.