Predicates with LocalDate (joda-time) in 3.3.1

245 views
Skip to first unread message

Rune

unread,
Oct 13, 2014, 10:55:10 AM10/13/14
to haze...@googlegroups.com
Hi

We have tried to upgrade from Hazelcast 3.2.3 to 3.3.1. 

When running our integration-tests a lot of tests are now failing, and digging a bit further into this, it seems that Predicates that used to return entries from a map, no longer does so. 
(downgrading to 3.2.3 makes all tests green again)

Example. 

public static Predicate isOwnerIdAndEnrollmentBefore(long ownerId, LocalDate date, Comparable... extras) {
        EntryObject e = entry();
        return matchesAll(e.get(OWNER_ID).equal(ownerId).and(e.get(ENROLLMENT_DATE).lessThan(date)), extras);
    }


The problem is the code marked with red. 
If we remove this AND clause, the predicate returns values in the map (although too many).
When using the AND clause, no values are found. 
And as mentioned, this works in 3.2.3. 

ENROLLMENT_DATE is a field in our pojo, a joda-time LocalDate. This is serialized as a long in the maps (with kryo).


I have tried to scan the docs / release notes for changes to date comparison / predicate builder etc, but have found nothing. 
Am I missing something obvious here? 


Here is the matchesAll method, I include it, but it should not affect the problem 


private static Predicate matchesAll(PredicateBuilder start, Comparable... extras) {
        PredicateBuilder combined = start;
        EntryObject e = start == null ? entry() : start.getEntryObject();
        for (Comparable value : extras) {
            PredicateBuilder current;
            if (value instanceof Gender) {
                current = e.get("gender").equal(value);
            } else if (value instanceof Category) {
                current = e.get(CATEGORY).equal(value);
            } else if (value instanceof Group) {
                Group group = (Group) value;
                if (group.equals(Young)) {
                    current = e.get(CATEGORY).in(YoungDairyStock_10, YoungBeefStock_11);
                } else {
                    current = e.get(CATEGORY).in(MilkingCow_12, DualPurposeCow_13, SucklerCow_14);
                }
            } else {
                throw new TineHzException("Matching entry for value [" + value + "] not supported");
            }
            combined = combined == null ? current : combined.and(current);
        }
        return combined;

    }

Rune

unread,
Oct 14, 2014, 4:48:40 AM10/14/14
to haze...@googlegroups.com
Please don't look at the matchesAll - it's just confusing, and it's not related to the problem

Rune

unread,
Oct 14, 2014, 5:15:05 AM10/14/14
to haze...@googlegroups.com
I have debugged this now, and think I have found something interesting. 
I set a breakpoint a epsMap.values(<mypredicate>) and stepped into hazelcast source from there

This is from com.hazelcast.query.impl.IndexImpl.

    @Override
    public Set<QueryableEntry> getSubRecords(ComparisonType comparisonType, Comparable searchedValue) {
        MultiResultSet results = new MultiResultSet();
        if (attributeType != null) {
            indexStore.getSubRecords(results, comparisonType, convert(searchedValue));
        }
        return results;
    }

the predicate query returns 0 results as the attributeType is null
I believe the type should be org.joda.time.LocalDate
This is the predicate query string: 
PredicateBuilder{
(ownerId=165 AND enrollmentDate<2013-01-01)
}


When querying for a Long, the attributeType is not null, but LONG ->  (com.hazelcast.query.impl.AttributeType@8708}"LONG"
This is the predicate query string: 
PredicateBuilder{
ownerId=165
}

Do I need to register converters?
This was not required in 3.2.3 (or 3.2.6 which we have upgraded to now)

This is from the v.3.2.2 tag
public Set<QueryableEntry> getSubRecords(ComparisonType comparisonType, Comparable searchedValue) {
        MultiResultSet results = new MultiResultSet();
        indexStore.getSubRecords(results, comparisonType, convert(searchedValue));
        return results;
    }

    
So my conclusion is that this null-check is introduced in 3.3 and therefore predicates for types other than the ones in com.hazelcast.query.impl.AttributeType will not work. 
For the record, both attributes are indexed.



Rune

unread,
Oct 14, 2014, 5:39:22 AM10/14/14
to haze...@googlegroups.com
I have also checked out the code for version 3.2.2 from github and removed the attributeType check and then built locally.

My tests are now running fine.  
 
And by the way. LocalDate is implementing Comparable via
-> public interface ReadablePartial extends Comparable<ReadablePartial> 

Rune

unread,
Oct 14, 2014, 8:32:12 AM10/14/14
to haze...@googlegroups.com
As mentioned in previous post - both attributes are indexed. 

When removing the index for the LocalDate attribute, the tests run without failures



Reply all
Reply to author
Forward
0 new messages