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

时间:2018-01-12 16:45:38

标签: java hazelcast hazelcast-imap

我想创建自己的自定义谓词来比较对象内部的复合id。需要是因为我必须在对象内部(复合id)上编写特定的日期比较逻辑。 我不想比较各个属性。我想使用复合ID,因为它来自调用者而我无法使用Predicate.in和Predicate.equals

我的对象结构如下

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 doc的最佳方法也没有指定。

有什么可以指导我怎么做吗?

1 个答案:

答案 0 :(得分:3)

@ oomph-fortuity,您的try { // connect to the database require_once 'connect.php'; // create a query to check if there are any records in the users table $querySelect = $conn->prepare("SELECT COUNT(userId) FROM users"); // run the query $querySelect->execute(); // fetch the result as an array indexed by column number as returned in the result set and turn it into a string $sajResult = json_encode( $querySelect->fetch(PDO::FETCH_NUM) ); $sajResult === '["0"]' ? $sUserRole = 1 : $sUserRole = 2; // create another query to insert into users $queryInsert = $conn->prepare("INSERT INTO users ( userName, firstName, lastName, password, image, userRoles_roleId ) VALUES ( :userName, :firstName, :lastName, :password, :image, :userRole )"); $queryInsert->bindParam( ':userName' , $sUserName ); $queryInsert->bindParam( ':firstName' , $sFirstName ); $queryInsert->bindParam( ':lastName' , $sLastName ); $queryInsert->bindParam( ':password' , $sPassword ); $queryInsert->bindParam( ':image' , $sImage ); $queryInsert->bindParam( ':userRole' , $sUserRole ); // run the query $bResult = $queryInsert->execute(); // send response to the client if the query is true or false $sjResponse = $bResult ? '{"status":"ok"}' : '{"status":"error"}'; echo $sjResponse; } catch (Exception $e) { echo "ERROR"; } 扩展DatePredicate,它实现AbstractPredicate并由内置的Hazelcast谓词使用。内置谓词可序列化工厂尝试反序列化您的类和&amp;失败,因为它只知道如何序列化/反序列化内置的谓词。

相反,只需实现IdentifiedDataSerializable interface:

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;
}
}

如果有效,请告诉我。