OpenLiberty / open-liberty

Open Liberty is a highly composable, fast to start, dynamic application server runtime environment
https://openliberty.io
Eclipse Public License 2.0
1.15k stars 592 forks source link

Entity identifier 'this' is broken for comparisons with time #29781

Open ajaypaul-ibm opened 1 month ago

ajaypaul-ibm commented 1 month ago

This error seems to be related to https://github.com/OpenLiberty/open-liberty/issues/28898 (which is closed). But here the comparison is happening between time values instead of numeric values. Query : SELECT this.numFullTimeWorkers FROM DemographicInfo WHERE this.collectedOn=:when

Exception stack :

An exception occurred while creating a query in EntityManager: 
Exception Description: Syntax error parsing [SELECT this.numFullTimeWorkers FROM DemographicInfo WHERE this.collectedOn=:when]. 
[52, 52] An identification variable must be provided for a range variable declaration.
ajaypaul-ibm commented 1 month ago

Eclipse link issue : https://github.com/eclipse-ee4j/eclipselink/issues/2275

ajaypaul-ibm commented 1 month ago

Recreate steps : Model :

@Entity
public class DemographicInfo {

    @Column
    public Instant collectedOn;

    @GeneratedValue
    @Id
    public BigInteger id;

    @Column
    public BigDecimal publicDebt;

    @Column
    public BigDecimal intragovernmentalDebt;

    @Column
    public BigInteger numFullTimeWorkers;

    public static DemographicInfo of(int year, int month, int day,
                                     long numFullTimeWorkers,
                                     double intragovernmentalDebt, double publicDebt) {
        DemographicInfo inst = new DemographicInfo();
        inst.collectedOn = ZonedDateTime.of(year, month, day, 12, 0, 0, 0, ZoneId.of("America/New_York")).toInstant();
        inst.numFullTimeWorkers = BigInteger.valueOf(numFullTimeWorkers);
        inst.intragovernmentalDebt = BigDecimal.valueOf(intragovernmentalDebt);
        inst.publicDebt = BigDecimal.valueOf(publicDebt);
        return inst;
    }

    @Override
    public String toString() {
        return "DemographicInfo from " + collectedOn;
    }
}

Test class :

 @Test
    // @SkipIfSysProp(DB_DB2) // Reference issue: https://github.com/OpenLiberty/open-liberty/issues/29443
    public void testOLGH29443() throws Exception {
        deleteAllEntities(DemographicInfo.class);

        ZoneId ET = ZoneId.of("America/New_York");
        Instant when = ZonedDateTime.of(2022, 4, 29, 12, 0, 0, 0, ET)
                .toInstant();

        DemographicInfo US2022 = DemographicInfo.of(2022, 4, 29, 132250000, 6526909395140.41, 23847245116757.60);
        DemographicInfo US2007 = DemographicInfo.of(2007, 4, 30, 121090000, 3833110332444.19, 5007058051986.64);

        List<BigInteger> results;

        tx.begin();
        em.persist(US2022);
        em.persist(US2007);
        tx.commit();

        List<Error> errors = new ArrayList<>();

        Thread.sleep(Duration.ofSeconds(1).toMillis());

        for (int i = 0; i < 10; i++) {
            System.out.println("Executing SELECT query, iteration: " + i);

            tx.begin();
            results = em
                    .createQuery("SELECT this.numFullTimeWorkers FROM DemographicInfo WHERE this.collectedOn=:when",
                            BigInteger.class)
                    .setParameter("when", when)
                    .getResultList();
            tx.commit();

            try {
                assertNotNull("Query should not have returned null after iteration " + i, results);
                assertFalse("Query should not have returned an empty list after iteration " + i, results.isEmpty()); // Recreate
                                                                                                                     // -
                                                                                                                     // an
                                                                                                                     // empty
                                                                                                                     // list
                                                                                                                     // is
                                                                                                                     // returned
                assertEquals("Query should not have returned more than one result after iteration " + i, 1,
                        results.size());
                assertEquals(US2022.numFullTimeWorkers, results.get(0));
            } catch (AssertionError e) {
                errors.add(e);
            }
        }

        if (!errors.isEmpty()) {
            throw new AssertionError(
                    "Executing the same query returned incorrect results " + errors.size() + " out of 10 executions",
                    errors.get(0));
        }
    }