我想创建自己的自定义谓词来比较对象内部的复合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的最佳方法也没有指定。
有什么可以指导我怎么做吗?
答案 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;
}
}
如果有效,请告诉我。