如何创建自己的自定义谓词以比较 hazelcast 中的复合 id

How to create own Custom Predicate to compare composite id in hazelcast

我想创建自己的客户谓词来比较复合 ID 的内部对象。需要是因为我必须在对象内部的对象(复合 id)上编写特定的日期比较逻辑。 我不想比较个人 attributes.i 想使用复合 id 因为它来自调用程序 我无法使用 Predicate.in 和 [=38 得到结果=]

我的对象结构如下

Birth{id=BirthId{name='b3', dob=Wed Jan 01 10:53:20 IST 1902}, name='b3', dob=Wed Jan 01 10:53:20 IST 1902, description='MNP'}

在 IMap 中,它的存储方式如下

key   : BirthId{name='b3', dob=Wed Jan 01 10:53:20 IST 1902}

value : Birth{id=BirthId{name='b3', dob=Wed Jan 01 10:53:20 IST 1902}, name='b3', dob=Wed Jan 01 10:53:20 IST 1902, description='MNP'}

我的Java类(出生和出生)结构如下

    public class Birth implements Serializable, Portable {

        private static final long serialVersionUID = 1L;

        private BirthId id;
        private String name;
        private Date dob;
        private String description;

        public BirthId getId() {
            return id;
        }

        public void setId(BirthId id) {
            this.id = id;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Date getDob() {
            return dob;
        }

        public void setDob(Date dob) {
            this.dob = dob;
        }

        public int hashCode() {
            return (new HashCodeBuilder()).append(this.id).append(this.name).append(this.dob).toHashCode();
        }

        public boolean equals(Object other) {
            if (other == this) {
                return true;
            } else if (!(other instanceof Birth)) {
                return false;
            } else {
                Birth rhs = (Birth) other;
                return (new EqualsBuilder()).append(this.id, rhs.id).append(this.name, rhs.name).append(this.dob, rhs.dob).isEquals();
            }
        }

        @Override public String toString() {
            return "Birth{" + "id=" + id + ", name='" + name + '\'' + ", dob=" + dob + ", description='" + description + '\'' + '}';
        }

        public int getFactoryId() {
            return 1;
        }

        public int getClassId() {
            return 1;
        }

        public void writePortable(PortableWriter portableWriter) throws IOException {
            portableWriter.writePortable("idComposite", getId());
            portableWriter.writeUTF("id", getId().toString());
            portableWriter.writeUTF("name", getName());
            portableWriter.writeUTF("description", getDescription());
            Date date = getDob();
            portableWriter.writeLong("dob", ((date == null) ? -1 : date.getTime()));
        }

        public void readPortable(PortableReader portableReader) throws IOException {
            setId((BirthId) portableReader.readPortable("idComposite"));
            setName(portableReader.readUTF("name"));
            setDescription(portableReader.readUTF("description"));
            long date = portableReader.readLong("dob");
            setDob(((date == -1) ? null : new Date(date)));
        }

    }

public class BirthId implements Comparable<BirthId>, Serializable, Portable {

    private static final long serialVersionUID = 1L;

    private String name;
    private Date dob;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getDob() {
        return dob;
    }

    public void setDob(Date dob) {
        this.dob = dob;
    }

    public int hashCode() {
        return (new HashCodeBuilder()).append(this.name).append(this.dob).toHashCode();
    }

    public boolean equals(Object other) {
        if (other == this) {
            return true;
        } else if (!(other instanceof BirthId)) {
            return false;
        } else {
            BirthId rhs = (BirthId) other;
            return (new EqualsBuilder()).append(this.name, rhs.name).append(this.dob, rhs.dob).isEquals();
        }
    }

    public int compareTo(BirthId rhs) {
        return this == rhs ? 0 : (null == rhs ? -1 : (new CompareToBuilder()).append(this.name, rhs.name).append(this.dob, rhs.dob).toComparison());
    }

    @Override public String toString() {
        return "BirthId{" + "name='" + name + '\'' + ", dob=" + dob + '}';
    }

    public int getFactoryId() {
        return 1;
    }

    public int getClassId() {
        return 2;
    }

    public void writePortable(PortableWriter portableWriter) throws IOException {
        portableWriter.writeUTF("name", getName());
        Date date = getDob();
        portableWriter.writeLong("dob", ((date == null) ? -1 : date.getTime()));
    }

    public void readPortable(PortableReader portableReader) throws IOException {
        setName(portableReader.readUTF("name"));
        long date = portableReader.readLong("dob");
        setDob(((date == -1) ? null : new Date(date)));
    }

    public static ClassDefinition getClassDefinition(int portableVersion) {
        ClassDefinitionBuilder result = new ClassDefinitionBuilder(1, 2, portableVersion);
        result.addUTFField("name");
        result.addLongField("dob");
        return result.build();
    }

}

我创建了自己的自定义谓词来比较如下日期

public class DatePredicate extends AbstractPredicate<Comparable, BirthId> {

    Comparable[] values;
    private volatile Set<Comparable> convertedInValues;

    public DatePredicate() {
    }

    public DatePredicate(String attribute, Comparable... values) {
        if (values == null) {
            throw new NullPointerException("Array can't be null");
        } else {
            this.values = values;
        }
    }

    protected boolean applyForSingleAttributeValue(Map.Entry entry, Comparable attributeValue) {

        //My own date comparison logic
        return true;
    }

    public int getId() {
        return 99;
    }
}

来电代码是

Predicate p = new DatePredicate("id", new BirthId("12345",passSpecifiedDate()));
Result res = imap.values(p);

我遇到了以下错误

Exception in thread "main" com.hazelcast.nio.serialization.HazelcastSerializationException: com.hazelcast.internal.serialization.impl.ArrayDataSerializableFactory@5f007be3 is not be able to create an instance for id: 99 on factoryId: -32

我不知道创建自己的自定义谓词的最佳方法,而且 hazelcast 文档也没有指定。

可以指导我如何操作吗?

@oomph-fortuity,您的 DatePredicate 扩展了 AbstractPredicate,它实现了 IdentifiedDataSerializable 并被内置的 Hazelcast 谓词使用。内置谓词可序列化工厂尝试反序列化您的 class 并失败,因为它只知道如何 serialize/deserialize 内置谓词。

相反,只需实现 com.hazelcast.query.Predicate 接口:

class DatePredicate implements Predicate<BirthId, Birth> {

BirthId birthIdToCompare;

public DatePredicate() {
}

public DatePredicate(BirthId birthId) {
    this.birthIdToCompare = birthId;
}

@Override
public boolean apply(Map.Entry<BirthId, Birth> mapEntry) {
    BirthId key = mapEntry.getKey();
    ///your custom logic
    return true;
}
}

然后这样调用

Predicate p = new DatePredicate(new BirthId("12345",passSpecifiedDate()));
Result res = imap.values(p);

如果可行,请告诉我。