Hazelcast query in custom objects
Asked Answered
F

1

6

I'm using Hazelcast as a shared map in my application. My map is like that:

Map<String, MyObject>

and MyObject:

class MyObject implements Serializeble {
    // Map FieldName -> FieldValue
    Map<String, Object> myMap;
}

So I'd like to use Hazelcast distributed query support to query in my object. I've checked that Hazelcast uses get's method to retrieve the object value, but in my case I don't have a get, instead of I'd like to implement my own getField like:

Object getField(String fieldName) {
    return myMap[fieldName];
}

And force Hazelcast to call this method. As a workaround, I've hacked Hazelcast code to use a CustomGetter in the class

/hazelcast/src/main/java/com/hazelcast/query/impl/ReflectionHelper.java

line 144:

if (localGetter == null) {
    localGetter = new CustomFieldGetter(name, obj);
}

and here My CustomFieldGetter class:

static class CustomFieldGetter extends Getter {
    final Object value;
    final Class type;
    final String fieldName;

    CustomFieldGetter(String fieldName, Object obj) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        super(null);
        this.fieldName = fieldName;
        this.value = obj.getClass().getMethod("getField", String.class).invoke(obj, fieldName);
        this.type = value.getClass();
    }

    @Override
    Object getValue(Object obj) throws Exception {
        return value;
    }

    @Override
    Class getReturnType() {
        return type;
    }

    @Override
    boolean isCacheable() {
        return false;
    }

    @Override
    public String toString() {
        return "FieldGetter [parent=" + parent + ", field=" + fieldName + "]";
    }
}

Ok cool, after recompilation of Hazelcast, and using this new jar, I could reach queries using plain sql. But for pagingQueries I got some errors.

So my finally question is: I'd like to avoid hack Hazelcast code (for further updates). Does Hazelcast has some supports on this issue? Is there any other solution for this problem?

PS: I'm using Hazelcast version -> hazelcast-3.3-RC3

Thanks in advance.

Frangipane answered 29/8, 2014 at 14:53 Comment(2)
Instead of posting this to Stackoverflow it would be way more meaningful to create a pullrequest with the patch or create a feature request in the bugtracker. We don't search for requests on the net, what is not on github as an issue does not exists as a request :) Actually I'm not sure if it makes sense to add something like that, if you start this everyone comes with different ways, same as classloading. Getters / setters are defined by the bean spec, if you're not using them there is a very high chance no framework supports your way. PS: Why PP makes problems, no idea :)Glycogen
Thanks for your suggestion. I've shared this link in Hazelcast ML as well. The problem is, we cannot create getters and setters, as this classes is created on demand in real time (reload jvm is not an option here). I can't create a pull request, as it's too much particular to my problem, it's just a palliative solution until we get the best approach. Anyway I appreciate.Frangipane
H
3

one option is to implement Portable interface. Then you could write each entry as a separate field. This assumes the entry value implements the Portable interface as well.

Look at the sample code how to use Portable.

Height answered 2/9, 2014 at 8:7 Comment(4)
I think it does. It will use the fields from Portable instead of using reflection to invoke a getter.Height
I believe it will solve the problem. Implementing it right now. Let you know soon.Frangipane
Oh right because it supports partial deserialization it is implemented differently :)Glycogen
That's great to hear!Height

© 2022 - 2024 — McMap. All rights reserved.